FZU 2289 项链

Posted 啦啦啦天啦噜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FZU 2289 项链相关的知识,希望对你有一定的参考价值。

题意:中文题意,略

思路:这就是一个数学模型,你简化以后发现这样一个递推式,在m>3的时候成立,a[m]=(n-2)*a[n-1]+(n-1)*a[n-2];这时候就只能用矩阵加速了,还是熟悉的矩阵,熟悉的味道(只不过没有改快速幂的参数,T了)

代码:

#include <cstdio>
typedef long long LL;
const int maxn=1e5+7;
const LL MOD=1e9+7;
struct mat{
    long long a[30][30];
    int r,c;
    mat operator *(const mat &b)const{
        mat ret;
        for (int i=0;i<r;i++){
            for (int j=0;j<b.c;j++){
                ret.a[i][j]=0;
                for (int k=0;k<c;k++)
                    ret.a[i][j]+=a[i][k]*b.a[k][j],ret.a[i][j]%=MOD;
            }
        }
        ret.r=r;
        ret.c=b.c;
        return ret;
    }
    mat init_unit(int x)
    {
        r=c=x;
        for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                if(i==j)a[i][j]=1;
                else a[i][j]=0;
            }
        }
    }
}unit;

mat pow(mat p,LL n){
    unit.init_unit(3);
    mat ans=unit;
    while(n){
        if(n&1)ans=p*ans;
        p=p*p;
        n>>=1;
    }
    return ans;
}
int main()
{
    LL n,m;
    while(~scanf("%I64d%I64d",&n,&m)){
        mat A;
        if(m<=3){
            if(m==1)printf("%I64d\n",n%MOD);
            else if(m==2)printf("%I64d\n",n*(n-1)%MOD);
            else if(m==3)printf("%I64d\n",n*(n-1)*(n-2));
            else printf("0\n");
            continue;
        }
        A.r=A.c=2;
        A.a[0][0]=(n-2)%MOD;
        A.a[0][1]=1;
        A.a[1][0]=(n-1)%MOD;
        A.a[1][1]=0;
        mat ans;
        ans=pow(A,m-3);
        mat tmp;
        tmp.a[0][0]=n*(n-1)*(n-2)%MOD;
        tmp.a[0][1]=n*(n-1)%MOD;
        ans=tmp*ans;
        printf("%I64d\n",ans.a[0][0]%MOD);
    }
    return 0;
}

 

以上是关于FZU 2289 项链的主要内容,如果未能解决你的问题,请参考以下文章

2017福建省赛 FZU2272~2283

FZU 2169 shadow

FZU 2020 组合 (Lucas定理)

HDU 2289 Cup

FZU 2122 又见LKity

「SDOI2009」HH的项链