来源自http://blog.csdn.net/chenguolinblog/article/details/10309423
hdu 1575
Tr A
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5587 Accepted Submission(s): 4200
Problem Description
A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973。
Input
数据的第一行是一个T,表示有T组数据。
每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。
Output
对应每组数据,输出Tr(A^k)%9973。
Sample Input
2 2 2 1 0 0 1 3 99999999 1 2 3 4 5 6 7 8 9
Sample Output
2 2686
裸矩阵快速幂。
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define LL long long 4 #define mod 9973 5 using namespace std; 6 typedef vector<LL> vec; 7 typedef vector<vec> mat; 8 mat mul(const mat &a,const mat &b) 9 { 10 int row=a.size(); 11 int col=b[0].size(); 12 int mid=b.size(); 13 mat c(row,vec(col)); 14 for(int i=0;i<row;i++) 15 for(int j=0;j<col;j++) 16 for(int k=0;k<mid;k++) 17 c[i][j]=(c[i][j]+a[i][k]*b[k][j]%mod)%mod; 18 return c; 19 } 20 mat quick_pow(mat a,LL n) 21 { 22 int len=a.size(); 23 mat res(len,vec(len)); 24 for(int i=0;i<len;i++) 25 res[i][i]=1; 26 while(n) 27 { 28 if(n&1) 29 res=mul(res,a); 30 a=mul(a,a); 31 n>>=1; 32 } 33 return res; 34 } 35 int main() 36 { 37 int T,n; 38 LL k,ansed; 39 scanf("%d",&T); 40 while(T--) 41 { 42 scanf("%d%lld",&n,&k); 43 mat ans(n,vec(n)); 44 for(int i=0;i<n;i++) 45 for(int j=0;j<n;j++) 46 scanf("%lld",&ans[i][j]); 47 ans=quick_pow(ans,k); 48 ansed=0; 49 for(int i=0;i<n;i++) 50 ansed=(ans[i][i]+ansed)%mod; 51 printf("%lld\n",ansed); 52 } 53 return 0; 54 }
hdu 1757
A Simple Math Problem
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5264 Accepted Submission(s): 3200
Problem Description
Lele now is thinking about a simple function f(x).
If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .
Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
Input
The problem contains mutiple test cases.Please process to the end of file.
In each case, there will be two lines.
In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
In the second line , there are ten integers represent a0 ~ a9.
Output
For each case, output f(k) % m in one line.
Sample Input
10 9999 1 1 1 1 1 1 1 1 1 1 20 500 1 0 1 0 1 0 1 0 1 0
Sample Output
45 104
裸矩阵快速幂。
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define LL long long 4 using namespace std; 5 typedef vector<LL> vec; 6 typedef vector<vec> mat; 7 int a[20]; 8 LL m,k,p,n; 9 mat mul(const mat &a,const mat &b,LL mod) 10 { 11 mat c(a.size(),vec(b[0].size())); 12 for(int i=0;i<a.size();i++) 13 for(int j=0;j<b[0].size();j++) 14 for(int k=0;k<b.size();k++) 15 { 16 c[i][j]=(c[i][j]%mod+a[i][k]*b[k][j]%mod)%mod; 17 } 18 return c; 19 } 20 mat quick_pow(mat a,LL n,LL mod) 21 { 22 int sized=a.size(); 23 mat res(sized,vec(sized)); 24 for(int i=0;i<10;i++) 25 res[i][i]=1; 26 while(n) 27 { 28 if(n&1) 29 { 30 res=mul(res,a,mod); 31 } 32 n>>=1; 33 a=mul(a,a,mod); 34 } 35 return res; 36 } 37 int main() 38 { 39 while(scanf("%lld%lld",&n,&m)!=EOF) 40 { 41 for(int i=0;i<10;i++) 42 scanf("%lld",&a[i]); 43 if(n<10) 44 { 45 printf("%lld\n",n%m); 46 continue; 47 } 48 mat multi(10,vec(10)); 49 mat ans(1,vec(10)); 50 for(int i=0;i<10;i++) 51 { 52 ans[0][i]=i; 53 multi[i][9]=a[9-i]; 54 } 55 for(int i=0;i<9;i++) 56 multi[i+1][i]=1; 57 multi=quick_pow(multi,n-9,m); 58 ans=mul(ans,multi,m); 59 printf("%lld\n",ans[0][9]); 60 } 61 return 0; 62 }