题目: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;
}