[POJ] 3233 Matrix Power Series

http://poj.org/problem?id=3233

 

等比数列求和,这里是等比矩阵求和,二分一下即可...

 

#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;

const int MAXN=32;

inline int rd(){
  int ret=0,f=1;char c;
  while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
  while(isdigit(c))ret=ret*10+c-'0',c=getchar();
  return ret*f;
}

int n,k,MOD;

struct Mat{
  int data[MAXN][MAXN];
  Mat(){memset(data,0,sizeof(data));}
  Mat operator*(const Mat &rhs){
    Mat ret;
    for(int k=1;k<=n;k++)
      for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          ret.data[i][j]=(ret.data[i][j]+data[i][k]*rhs.data[k][j])%MOD;
    return ret;
  }
  Mat operator+(const Mat &rhs){
    Mat ret;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++)
        ret.data[i][j]=(data[i][j]+rhs.data[i][j])%MOD;
    return ret;
  }
}A,empty;

Mat pow(int x){
  Mat ret,base=A;
  for(int i=1;i<=n;i++)ret.data[i][i]=1;
  while(x){
    if(x&1) ret=ret*base;
    base=base*base;
    x>>=1;
  }
  return ret;
}

Mat solve(int x){
  Mat ret;
  if(x==1) return A;
  if(x==0) {return empty;}
  if(x&1){
    ret=solve((x-1)/2);
    return ret+ret*pow((x+1)/2)+pow((x+1)/2);
  }
  ret=solve(x/2);
  return ret+ret*pow(x/2);
}

int main(){
  cin>>n>>k>>MOD;
  for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
      A.data[i][j]=rd();
  for(int i=1;i<=n;i++) empty.data[i][i]=1;
  Mat ans=solve(k);
  for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++)
      printf("%d ",ans.data[i][j]);
    putchar('\n');
  }
  return 0;
}

 

posted @ 2018-07-02 16:22  GhostCai  阅读(119)  评论(1编辑  收藏  举报