标签:快速 contract ges 技术 alt i+1 rac sed problem
题目链接:Recursive sequence
题意:给出n头母牛,第一头报a,第二头报b,第i头报f[i-2]*2+f[i-1]+i^4,问第n头母牛报数多少
分析:N,a,b<2^31,果断矩阵快速幂,关键是要推出公式,公式如下,仅作参考
1 0 0 0 0 0 0 1 1
1 1 0 0 0 0 0 i i+1
1 2 1 0 0 0 0 i2 (i+1)2
1 3 3 1 0 0 0 * i3 = (i+1)3
1 4 6 4 1 0 0 i4 (i+1)4
0 0 0 0 0 0 1 f[i-2] f[i-1]
0 0 0 0 1 2 1 f[i-1] f[i]
推出公式后,代入矩阵快速幂,就解决了,代码如下
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 8 using namespace std; 9 const long long mod = 2147493647; 10 struct prog 11 { 12 long long a[8][8]; 13 }; 14 prog s,B; 15 prog matrixmul(prog a,prog b) 16 { 17 prog c; 18 for(int i=1;i<8;++i)for(int j=1;j<8;++j) 19 { 20 c.a[i][j]=0; 21 for(int k=1;k<8;k++) 22 c.a[i][j]+=(a.a[i][k]*b.a[k][j])%mod; 23 c.a[i][j]%=mod; 24 } 25 return c; 26 } 27 prog mul(prog s,int k) 28 { 29 prog ans; 30 for(int i=1;i<8;++i)for(int j=1;j<8;++j) ans.a[i][j]=(i==j)?1:0; 31 while(k){ 32 if(k&1) 33 ans=matrixmul(ans,s); 34 k>>=1; 35 s=matrixmul(s,s); 36 } 37 return ans; 38 } 39 int main() 40 { 41 int n,t,a,b; 42 for(scanf("%d",&t);t--;){ 43 scanf("%d %d %d",&n,&a,&b); 44 if(n==1){printf("%lld\n",a%mod);continue;} 45 if(n==2){printf("%lld\n",b%mod);continue;} 46 if(n==3){printf("%lld\n",(81+2*a%mod+b%mod)%mod);continue;} 47 n-=2; 48 for(int i=1;i<=7;++i)for(int j=1;j<=7;++j) s.a[i][j]=0,B.a[i][j]=0; 49 for(int i=1; i<=5; i++)s.a[i][1]=1; 50 for(int i=2; i<=5; i++)s.a[i][2]=i-1; 51 s.a[3][3]=1;s.a[4][3]=3;s.a[5][3]=6; 52 s.a[4][4]=1;s.a[5][4]=4; 53 s.a[5][5]=1;s.a[6][5]=1; 54 s.a[6][6]=1;s.a[7][6]=1; 55 s.a[6][7]=2; 56 B.a[1][1]=1;B.a[2][1]=3;B.a[3][1]=9;B.a[4][1]=27;B.a[5][1]=81;B.a[6][1]=b;B.a[7][1]=a; 57 s=mul(s,n); 58 s=matrixmul(s,B); 59 printf("%lld\n",s.a[6][1]%mod); 60 } 61 return 0; 62 }
HDU5950-Recursive sequence(矩阵快速幂)
标签:快速 contract ges 技术 alt i+1 rac sed problem
原文地址:http://www.cnblogs.com/chendl111/p/6016756.html