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 项链的主要内容,如果未能解决你的问题,请参考以下文章