http://poj.org/problem?id=3735
大致题意:
有n仅仅猫,開始时每仅仅猫有花生0颗,现有一组操作,由以下三个中的k个操作组成:
1. g i 给i仅仅猫一颗花生米
2. e i 让第i仅仅猫吃掉它拥有的全部花生米
3. s i j 将猫i与猫j的拥有的花生米交换
现将上述一组操作循环m次后,问每仅仅猫有多少颗花生?
非常明显,要先构造矩阵。构造一个(n+1)*(n+1)的矩阵a,初始化为单位矩阵。
g i : a[i][n+1] += 1;
e i : a[i][j] = 0;(1 <= j <= n+1)
s i j : swap(a[i][k],a[j][k])(1 <= k <= n+1)
然后矩阵高速幂就ok了。
注意m非常大,k也不小,要用long long .
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> #define LL long long #define _LL __int64 #define eps 1e-12 #define PI acos(-1.0) #define C 240 #define S 20 using namespace std; const int maxn = 110; int n,m,k; struct matrix { LL mat[maxn][maxn]; void init() { memset(mat,0,sizeof(mat)); for(int i = 1; i <= n+1; i++) mat[i][i] = 1; } }a,b; matrix mul(matrix a, matrix b) { matrix ans; memset(ans.mat,0,sizeof(ans.mat)); for(int i = 1; i <= n+1; i++) { for(int k = 1; k <= n+1; k++) { if(a.mat[i][k] == 0) continue; for(int j = 1; j <= n+1; j++) ans.mat[i][j] += a.mat[i][k] * b.mat[k][j]; } } return ans; } matrix pow(matrix a, int nn) { matrix ans; ans.init(); while(nn) { if(nn&1) ans = mul(ans,a); a = mul(a,a); nn >>= 1; } return ans; } int main() { char ch[3]; int x,y; while(~scanf("%d %d %d",&n,&m,&k)) { if(n == 0 && m == 0 && k == 0) break; a.init(); memset(b.mat,0,sizeof(b.mat)); b.mat[n+1][1] = 1; while(k--) { scanf("%s",ch); if(ch[0] == 'g') { scanf("%d",&x); a.mat[x][n+1] += 1; } else if(ch[0] == 'e') { scanf("%d",&x); for(int i = 1; i <= n+1; i++) a.mat[x][i] = 0; } else { scanf("%d %d",&x,&y); for(int i = 1; i <= n+1; i++) swap(a.mat[x][i],a.mat[y][i]); } } a = pow(a,m); matrix ans = mul(a,b); for(int i = 1; i <= n; i++) { printf("%lld",ans.mat[i][1]); if(i == n) printf(" "); else printf(" "); } } return 0; }