POJ 3233 Matrix Power (矩阵快速幂+等比数列求和)

来源:互联网 发布:时时彩发计划软件 编辑:程序博客网 时间:2024/05/16 00:56

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 35using 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;}
阅读全文
0 0