Training little cats

题目:https://cn.vjudge.net/problem/POJ-3735

已知有n只猫咪,开始时每只猫咪有花生米0颗,先有一组操作:
由下面三个中的k个操作组成:
g i 给i只猫咪一颗花生米
e i 让第i只猫咪吃掉它拥有的所有花生米
s i j 将猫咪i与猫咪j的拥有的花生米交换

  现将上述操作做m次后,问每只猫咪有多少颗花生米?

因m的数据范围较大,用矩阵连乘优化。

初始化矩阵

g i 即在第i列的最后一行加1

s i j 即交换第i,j列

e i  将第i列全部置为0

 

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,k;
struct mat {long long v[101][101];}A,T;
mat cheng(const mat &a, const mat &b){
mat tmp;
memset(tmp.v,0,sizeof(tmp.v));
for(int k=0; k<=n;k++){
for(int i=0;i<=n;i++) {
if(a.v[i][k])
for(int j=0;j<=n;j++)
tmp.v[i][j]+=a.v[i][k]*b.v[k][j];}
}
return tmp;
}
mat fang(mat x, int n) {
mat tmp;
memset(tmp.v,0,sizeof(tmp.v));
for(int i=0;i<101;i++) tmp.v[i][i]=1;
while(n) {
if(n&1)tmp=cheng(tmp,x);
x=cheng(x,x);n>>=1;}
return tmp;
}
int main() {
char s[2];
int a,b;
while(~scanf("%d%d%d",&n,&m,&k)) {
if(!(n+m+k)) break;
memset(A.v,0,sizeof(A.v));
A.v[0][0]=1;
memset(T.v,0,sizeof(T.v));
for(int i=0;i<101;i++) T.v[i][i]=1;
for(int i=0;i<k;i++) {
cin>>s;cin>>a;
if(s[0]=='g'){T.v[0][a]++;}
else if(s[0]=='e') {for(int i=0;i<=n;i++) T.v[i][a]=0;}
else {cin>>b;for(int i=0;i<=n;i++) swap(T.v[i][a],T.v[i][b]);}
}
mat ans;
ans=cheng(A,fang(T,m));
for(int i=1;i<=n;i++) cout<<ans.v[0][i]<<" ";
cout<<endl;
}
return 0;}

 

posted @ 2017-07-10 15:47  0degreeofsail  阅读(92)  评论(0编辑  收藏  举报