poj 3233(矩阵快速幂+二分)

来源:互联网 发布:linux tomcat常用命令 编辑:程序博客网 时间:2024/05/17 06:45
Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072KTotal Submissions: 19323 Accepted: 8152

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 40 11 1

Sample Output

1 22 3

Source

POJ Monthly--2007.06.03, Huang, Jinsong

a^1+a^2+a^3+a^4+a^5=(a^1+a^2+a^3+a^4)+a^5

(a^1+a^2+a^3+a^4)=(a^1+a^2+a^2(a^1+a^2))=(a^1+a^2)*(1+a^2)

(a^1+a^2)=a^1(1+a^1)

#include <algorithm>#include <iostream>#include <stdio.h>#include <string.h>using namespace std;int n,k,m;struct Matrix{    int ma[30][30];}p,q;Matrix Multi(Matrix a,Matrix b){    Matrix res;    memset(res.ma,0,sizeof(res.ma));    for(int i=0;i<n;i++)        for(int j=0;j<n;j++)            for(int k=0;k<n;k++)                res.ma[i][j]=(res.ma[i][j]+a.ma[i][k]*b.ma[k][j])%m;    return res;}Matrix quick_pow(Matrix m,int k){    Matrix res=q;    while(k)    {        if(k&1)            res=Multi(res,m);        k>>=1;        m=Multi(m,m);    }    return res;}Matrix sum(Matrix a,Matrix b){    for(int i=0;i<n;i++)        for(int k=0;k<n;k++)            a.ma[i][k]=(a.ma[i][k]+b.ma[i][k])%m;    return a;}Matrix recursion(Matrix m,int k){    if(k==1)        return m;    else if(k&1)        return sum(recursion(m,k-1),quick_pow(m,k));    else        return Multi(recursion(m,k/2),sum(q,quick_pow(m,k/2)));}int main(){    while(~scanf("%d%d%d",&n,&k,&m))    {        memset(q.ma,0,sizeof(q.ma));        for(int i=0;i<n;i++)            q.ma[i][i]=1;        for(int i=0;i<n;i++)            for(int k=0;k<n;k++)                scanf("%d",&p.ma[i][k]);        Matrix res;        res=recursion(p,k);        for(int i=0;i<n;i++)        {            for(int k=0;k<n-1;k++)                printf("%d ",res.ma[i][k]);            printf("%d\n",res.ma[i][n-1]);        }    }    return 0;}


0 0