lightoj 1052 - String Growth & uva 12045 - Fun with Strings 矩阵
思路:很容易发现规律,数列和Fib数列一样的。
记开始的时候啊a的个数为Y,b的个数为X。建立矩阵。
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define M 105 7 #define eps 1e-6 8 #define ll long long 9 #define mod 1000000007 10 using namespace std; 11 struct mat 12 { 13 ll m[2][2]; 14 }; 15 mat Mul(mat a,mat b) 16 { 17 mat ans; 18 for(int i=0;i<2;i++) 19 for(int j=0;j<2;j++){ 20 ans.m[i][j]=0; 21 for(int k=0;k<2;k++) 22 ans.m[i][j]+=a.m[i][k]*b.m[k][j]; 23 ans.m[i][j]%=mod; 24 } 25 return ans; 26 } 27 mat Pow(int n) 28 { 29 mat ans,a; 30 for(int i=0;i<2;i++) 31 for(int j=0;j<2;j++){ 32 ans.m[i][j]=(i==j); 33 a.m[i][j]=1; 34 } 35 a.m[0][0]=0; 36 while(n){ 37 if(n&1) ans=Mul(ans,a); 38 n>>=1; 39 a=Mul(a,a); 40 } 41 return ans; 42 } 43 ll x,y,X,Y; 44 bool solve(int n,int m) 45 { 46 mat a,b,c; 47 ll a1,a2,b1,b2; 48 if(n!=1){ 49 a=Pow(n-1); 50 a1=a.m[0][0]+a.m[1][0]; 51 a2=a.m[0][1]+a.m[1][1]; 52 } 53 else a1=a2=1; 54 if(m!=1){ 55 b=Pow(m-1); 56 b1=b.m[0][0]+b.m[1][0]; 57 b2=b.m[0][1]+b.m[1][1]; 58 } 59 else b1=b2=1; 60 ll t1=x*b1-y*a1; 61 ll t3=a2*y-x*b2; 62 ll t2=b1*a2-b2*a1; 63 if(t3%t2!=0||t1%t2!=0) return 0; 64 X=t1/t2; 65 Y=t3/t2; 66 if(X<0||Y<0) return 0; 67 return 1; 68 } 69 int main() 70 { 71 int t,ca=0,n,m,k; 72 scanf("%d",&t); 73 while(t--){ 74 scanf("%d%lld%d%lld%d",&n,&x,&m,&y,&k); 75 printf("Case %d: ",++ca); 76 if(!solve(n,m)) printf("Impossible\n"); 77 else{ 78 if(k==1){ 79 printf("%lld\n",(X+Y)%mod); 80 continue; 81 } 82 mat a=Pow(k-1); 83 ll ans=(a.m[0][0]+a.m[1][0])*Y+(a.m[0][1]+a.m[1][1])*X; 84 printf("%lld\n",ans%mod); 85 } 86 } 87 return 0; 88 }