首页 > 其他 > 详细

FZU 2289 项链

时间:2018-06-06 16:34:59      阅读:163      评论:0      收藏:0      [点我收藏+]

题意:中文题意,略

思路:这就是一个数学模型,你简化以后发现这样一个递推式,在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 项链

原文:https://www.cnblogs.com/lalalatianlalu/p/9145826.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!