题目:Harry Potter and Cyber Sequence Generator
题意,有两个容器C1,C2,初始的时候C1中有一个数的值为V,给你K个操作,每次都重复这K个操作N遍,最后问你C2中的数是
多少。N<=10^100。
1:循环操作的次数巨大,敏感的想到这是矩阵连乘的题目。
2:K个操作可以得出一个矩阵,N个K操作就是这个矩阵的N次方
3:最后再乘以初始矩阵即可
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; typedef long long LL; const LL MOD=1000000007; const int N=3; struct Matrix { LL m[N][N]; }; Matrix per={1,0,0,0,1,0,0,0,1}; Matrix multi(Matrix a,Matrix b) { Matrix c; int i,j,k; for(i=0;i<N;i++) { for(j=0;j<N;j++) { c.m[i][j]=0; for(k=0;k<N;k++) { c.m[i][j]+=(a.m[i][k]%MOD*(b.m[k][j]%MOD))%MOD; c.m[i][j]%=MOD; } } } return c; } Matrix matrix_mod(Matrix a,LL k) { Matrix ans=per,p=a; while(k) { if(k&1) { ans=multi(ans,p); k--; } k>>=1; p=multi(p,p); } return ans; } LL getNum(char *str) { LL ans=0; int len=strlen(str); for(int i=0;i<len;i++) ans=ans*10+str[i]-'0'; return ans; } int main() { Matrix ans,tmp1; LL T,V,Q,cas=1; char str[105]; char str1[105]; char str2[105]; char str3[105]; cin>>T; while(T--) { cin>>V; ans=per; while(cin>>str1) { if(str1[0]=='E') break; cin>>str2>>str3; tmp1=per; if(str1[0]=='S') { if(strcmp(str2,"C1,")==0&&strcmp(str3,"C2")==0) { tmp1.m[0][0]=0; tmp1.m[1][0]=1; } else if(strcmp(str2,"C2,")==0&&strcmp(str3,"C1")==0) { tmp1.m[0][1]=1; tmp1.m[1][1]=0; } else if(strcmp(str2,"C1,")==0&&strcmp(str3,"C1")!=0) { tmp1.m[0][0]=0; tmp1.m[2][0]=getNum(str3); } else if(strcmp(str2,"C2,")==0&&strcmp(str3,"C2")!=0) { tmp1.m[1][1]=0; tmp1.m[2][1]=getNum(str3); } } if(str1[0]=='A') { if(strcmp(str2,"C1,")==0&&strcmp(str3,"C1")==0) tmp1.m[0][0]=2; else if(strcmp(str2,"C2,")==0&&strcmp(str3,"C2")==0) tmp1.m[1][1]=2; else if(strcmp(str2,"C1,")==0&&strcmp(str3,"C2")==0) tmp1.m[1][0]=1; else if(strcmp(str2,"C2,")==0&&strcmp(str3,"C1")==0) tmp1.m[0][1]=1; else if(strcmp(str2,"C1,")==0) tmp1.m[2][0]=getNum(str3); else tmp1.m[2][1]=getNum(str3); } if(str1[0]=='M') { if(strcmp(str2,"C1,")==0) tmp1.m[0][0]=getNum(str3); else tmp1.m[1][1]=getNum(str3); } ans=multi(ans,tmp1); } cin>>Q; cout<<"Case "<<cas++<<":"<<endl; while(Q--) { cin>>str; LL ret=0; int len=strlen(str); for(int i=0;i<len;i++) { ret=ret*10+str[i]-'0'; ret%=(MOD-1); } Matrix final=matrix_mod(ans,ret); LL sum=(final.m[0][1]%MOD*(V%MOD)%MOD+final.m[2][1]%MOD)%MOD; cout<<sum<<endl; } } return 0; }