poj 3233 Matrix Power Series ——矩阵快速幂+二分求解

April 2, 2013
POJ Math

Description Input Output Sample Input Sample Output


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <stack>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
#define LL long long
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
typedef struct matrix{
  int a[33][33];
}matrix;
matrix A, B, per;
int m, k, n;
void init(){
  scanf("%d%d%d", &n, &k, &m);
  for (int i = 0; i < n; ++i){
    for (int j = 0; j < n; ++j){
      scanf("%d", &A.a[i][j]);
      A.a[i][j] %= m;
      per.a[i][j] = (i == j);
    }
  }
}
matrix add(matrix a, matrix b){
  matrix c;
  for (int i = 0; i < n; ++i){
    for (int j = 0; j < n; ++j){
      c.a[i][j] = 0; c.a[i][j] = (a.a[i][j] + b.a[i][j]) % m;
    }
  }
  return c;
}
matrix multi(matrix a, matrix b){
  matrix c;
  for (int i = 0; i < n; ++i){
    for (int j = 0;j < n; ++j){
      c.a[i][j] = 0;
      for (int k = 0; k < n; ++k){
        c.a[i][j] += (((a.a[i][k]%m) * (b.a[k][j]%m))%m);
      }
    }
  }
  return c;
}
matrix pow(int k){
  matrix ans = per, m = A;
  while (k){
    if (k&1){
      ans = (multi(ans, m)); k--;
    }
    k >>= 1; m = multi(m, m);
  }
  return ans;
}
matrix maxsum(int k){
  if (k == 1) return A;
  matrix temp = maxsum(k/2), b;
  if (k&1){
    b = pow(k/2+1); temp = add(temp, multi(temp, b));
    temp = add(temp, b);
  }
  else{
    b = pow(k/2); temp = add(temp, multi(temp, b));
  }
  return temp;
}

int main(void){
#ifndef ONLINE_JUDGE
  freopen("3233.in", "r", stdin);
#endif
  init();
  matrix ans = maxsum(k);
  int j, i;
  for (i = 0; i < n; ++i){
    for (j = 0; j < n-1; ++j){
      printf("%d ", ans.a[i][j]);
    }
    printf("%d\n", ans.a[i][j]);
  }

  return 0;
}

注意,求快速幂的时候,先把ans赋值成单位矩阵。 有时间认真写一下快速幂的思想。 突然赶脚自己的代码写得很挫……

comments powered by Disqus