对每个0<=i<n求f(g(i))的和,其中f(x)为斐波那契数列第x项,g(i)=k*i+b,k,b,n给定,模数给定。
斐波那契数有一种用矩阵乘法求的方法,这个矩阵A自己写,令F[i]为i和i+1的那个矩阵,F[i]=A^b*F[0],然后答案要求F[b]+F[k+b]+F[k*2+b]+……=(A^b+A^(k+b)+A^(2k+b)+……)*F[0]=(E+A^k+……+A^k^(n-1))*A^b*F[0]的[2,1]项。上面括号里就令B=A^k求E+B+B^2+……+B^(n-1),可以求吧!
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 //#include<iostream> 6 using namespace std; 7 8 #define LL long long 9 LL K,b,n,mod; 10 typedef LL mat[5][5]; 11 mat ans,base,E,a,f,t; 12 void copy(mat &a,mat b) 13 { 14 for (int i=1;i<=2;i++) 15 for (int j=1;j<=2;j++) 16 a[i][j]=b[i][j]; 17 } 18 void mul(mat a,mat b,mat &ans) 19 { 20 mat t; 21 memset(t,0,sizeof(t)); 22 for (int i=1;i<=2;i++) 23 for (int j=1;j<=2;j++) 24 for (int k=1;k<=2;k++) 25 t[i][j]=(t[i][j]+a[i][k]*b[k][j]%mod)%mod; 26 copy(ans,t); 27 } 28 void add(mat a,mat b,mat &ans) 29 { 30 for (int i=1;i<=2;i++) 31 for (int j=1;j<=2;j++) 32 ans[i][j]=a[i][j]+b[i][j]; 33 } 34 void init(mat &a) 35 { 36 a[1][1]=a[2][2]=1; 37 a[1][2]=a[2][1]=0; 38 } 39 void pow(mat a,LL b,mat &ans) 40 { 41 mat t,tmp;init(t);copy(tmp,a); 42 while (b) 43 { 44 if (b&1) mul(t,tmp,t); 45 mul(tmp,tmp,tmp); 46 b>>=1; 47 } 48 copy(ans,t); 49 } 50 void sum(mat a,LL b,mat &ans) 51 { 52 mat last,tmp,f,t; 53 memset(ans,0,sizeof(ans)); 54 init(f);init(last); 55 copy(tmp,a); 56 while (b) 57 { 58 if (b&1) 59 { 60 mul(f,last,t); 61 add(ans,t,ans); 62 mul(last,tmp,last); 63 } 64 add(tmp,E,t); 65 mul(f,t,f); 66 mul(tmp,tmp,tmp); 67 b>>=1; 68 } 69 } 70 int main() 71 { 72 a[1][1]=a[1][2]=a[2][1]=1;a[2][2]=0; 73 E[1][1]=E[2][2]=1;E[1][2]=E[2][1]=0; 74 while (~scanf("%lld%lld%lld%lld",&K,&b,&n,&mod)) 75 { 76 ans[1][1]=1;ans[1][2]=ans[2][1]=ans[2][2]=0; 77 pow(a,b,t);mul(t,ans,ans); 78 pow(a,K,base);sum(base,n,f); 79 mul(f,ans,ans); 80 printf("%lld\n",ans[2][1]); 81 } 82 return 0; 83 }