Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072K
Total Submissions: 23165 Accepted: 9651
Description
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
Input
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.
Output
Output the elements of S modulo m in the same way as A is given.
Sample Input
2 2 4
0 1
1 1
Sample Output
1 2
2 3
Source
POJ Monthly–2007.06.03, Huang, Jinsong
- 错误总结
今天才知道取模操作多了就会超时以及数组开大了会RE。。。可怕,乘法里先是取了两次模就超时了,取一次 1800MS,嗯,又多了一种TLE和RE的姿势,还需要努力啊。
- 其中等比数列的求和其实是二分求解的操作,当K为偶数时,F(A,k)=F(A,k/2)(A^k/2+E),当k为奇数时,F(A,k)=F(A,k/2)(A^(k+1/2)+E)+A^(k+1/2)
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1000
#define kuma 35
using namespace std;
typedef long long ll;
ll mod;
ll n;
struct matrix
{
ll a[kuma][kuma];//数组开大了居然会RE.....
};
matrix E;
matrix mul(matrix x,matrix y)
{
matrix ans=E;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
ans.a[i][j]=0;
for(int k=0;k<n;k++)
{
ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j])%mod;//取模取多了居然会TLE....
}
}
}
return ans;
}
matrix add(matrix x,matrix y)
{
matrix ans=E;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
ans.a[i][j]=(x.a[i][j]+y.a[i][j])%mod;
}
}
return ans;
}
matrix quickpow(matrix a,ll p)
{
matrix ans;
ans=E;
matrix t;
t=a;
while(p!=0)
{
if(p&1)ans=mul(ans,t);
p>>=1;
t=mul(t,t);
}
return ans;
}
matrix dos(matrix A,int k)
{
if(k==1)return A;
if(k%2==0)
{
matrix t=dos(A,k/2);
return mul(add(quickpow(A,k/2),E),t);
}
else
{
matrix t=dos(A,k/2);
matrix q=quickpow(A,(k+1)/2);
return add(q,mul(t,add(q,E)));
}
}
void init()
{
for(int i=0;i<n;i++)
E.a[i][i]=1;
}
int main()
{
matrix nico;
int k;
scanf("%I64d%I64d%I64d",&n,&k,&mod);
init();
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%I64d",&nico.a[i][j]);
}
}
matrix ans=dos(nico,k);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
printf("%I64d ",ans.a[i][j]);
}
printf("\n");
}
return 0;
}