hdu 3658 How many words
思路:
构造矩阵,矩阵快速幂!!!
代码如下:
1 #include<cstdio> 2 #include<vector> 3 #include<cmath> 4 #include<iostream> 5 #include<cstring> 6 #define ll __int64 7 #define mod 1000000007 8 using namespace std; 9 int let[100]; 10 struct ma 11 { 12 ll a[60][60]; 13 }A,B; 14 ll sum(ma a) 15 { 16 ll ans=0; 17 for(int i=0;i<52;i++) 18 for(int j=0;j<52;j++) 19 ans=(ans+a.a[i][j])%mod; 20 return ans; 21 } 22 void init() 23 { 24 int i,j; 25 for(i='a';i<='z';i++){ 26 let[i-'a']=i; 27 let[i-'a'+26]=i-'a'+'A'; 28 } 29 for(i=0;i<52;i++) 30 for(j=0;j<52;j++){ 31 if(abs(let[i]-let[j])<=32) A.a[i][j]=1; 32 if(abs(let[i]-let[j])<32) B.a[i][j]=1; 33 } 34 } 35 ma mul(ma a,ma b) 36 { 37 ma ans; 38 for(int i=0;i<52;i++) 39 for(int j=0;j<52;j++){ 40 ans.a[i][j]=0; 41 for(int k=0;k<52;k++) 42 ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%mod; 43 } 44 return ans; 45 } 46 ma pows(ma a,int b) 47 { 48 ma ans; 49 for(int i=0;i<52;i++) 50 for(int j=0;j<52;j++) 51 ans.a[i][j]=(i==j); 52 while(b){ 53 if(b&1) ans=mul(ans,a); 54 b>>=1; 55 a=mul(a,a); 56 } 57 return ans; 58 } 59 int main() 60 { 61 init(); 62 int m,t; 63 scanf("%d",&t); 64 while(t--){ 65 scanf("%d",&m); 66 ll res=sum(pows(A,m-1))-sum(pows(B,m-1)); 67 if(res<0) res=(res%mod+mod)%mod; 68 printf("%I64d\n",res); 69 } 70 return 0; 71 }