n个培养皿排成一个圈,每个里面都有一些细菌。培养皿逆时针编号为1,2,…,n,第i个培养皿里有a[i]个细菌。细菌不停地活动着,它们有可能会进行六种操作:
d i 0,表示第i个培养皿的所有细菌都死亡。
r i k,表示第i个培养皿的每个细菌分裂成k个。
c i j,表示把第j个培养皿的所有细菌复制到第i个培养皿。
t i j,表示把第j个培养皿的所有细菌转移到第i个培养皿。
s i j,表示交换第i和第j两个培养皿的细菌。
m 0 0,表示每个培养皿的细菌都同时转移到它逆时针的下一个培养皿。
一旦某个培养皿里有超过s个细菌,每s个细菌会合在一起进化成一个高级组织而脱离培养皿,这些细菌重复的执行着m条命令(编号为1,2,…,m),即第X时刻执行第X mod m条命令。问在第t时刻执行命令后,每个培养皿各有多少个细菌?已知初始的时候每个培养皿恰好有一个细菌。
这道题是矩阵乘法加上快速幂,跟vijos 1049思路差不多,都是把所有的操作转为矩阵,然后乘在一起,变成一个半成品结果矩阵,之后这个半成品结果矩阵要平方t/m次(需要快速幂),不过,可能会有余数,所以剩下的要再单独模拟,最后,结果矩阵就诞生了,再用它乘初始序列(都为1),这道题就解决了。两题最大的区别就是矩阵构造来说,这道题复杂了一点。
(一开始都为单位矩阵,i,j,k与输入意思一样,看上面)
d操作:矩阵中的a[i][i]=0;
r操作:矩阵中的a[i][i]=k;
c操作:矩阵中的a[i][j]=1;
t操作:矩阵中的a[i][j]=1,a[j][j]=0;
s操作:矩阵中的a[i][i]=a[j][j]=0,a[i][j]=a[j][i]=1;
m操作:矩阵中的最后一行放到最上面;
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
int n,he;
struct node
{
long long a[110][110];
node()
{
memset(a,0,sizeof(a));
}
}pre[25];
node chengfa1(node a,node b)
{
node c;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%he;
}
}
}
return c;
}
node chengfa2(node a,node b)
{
node c;
for(int i=1;i<=n;i++)
{
for(int k=1;k<=n;k++)
{
c.a[i][1]=(c.a[i][1]+a.a[i][k]*b.a[k][1])%he;
}
}
return c;
}
int main()
{
int m,t;
char s[110];
node f,ans,ss;
scanf("%d%d%d%d",&n,&m,&t,&he);
for(int i=1;i<=n;i++)
{
f.a[i][1]=1;ans.a[i][i]=ss.a[i][i]=1;
for(int j=1;j<=m;j++)pre[j].a[i][i]=1;
}
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%s%d%d",s+1,&x,&y);
if(s[1]=='d')pre[i].a[x][x]=0;
if(s[1]=='r')pre[i].a[x][x]=y;
if(s[1]=='c')pre[i].a[x][y]=1;
if(s[1]=='t'){pre[i].a[x][y]=1;pre[i].a[y][y]=0;}
if(s[1]=='s')
{
pre[i].a[x][x]=pre[i].a[y][y]=0;
pre[i].a[x][y]=1;pre[i].a[y][x]=1;
}
if(s[1]=='m')
{
pre[i].a[1][1]=0;pre[i].a[1][n]=1;
for(int j=2;j<=n;j++)
{
pre[i].a[j][j]=0;pre[i].a[j][j-1]=1;
}
}
}
for(int i=1;i<=m;i++)ss=chengfa1(pre[i],ss);
int x=t/m;
if(x==1)ans=ss;
else
{
while(x>0)
{
if(x%2==1)ans=chengfa1(ss,ans);
ss=chengfa1(ss,ss);
x/=2;
}
}
if(t%m!=0)
{
for(int i=1;i<=(t-t/m*m);i++)ans=chengfa1(pre[i],ans);
}
f=chengfa2(ans,f);
for(int i=1;i<n;i++)printf("%lld ",f.a[i][1]);
printf("%lld\n",f.a[n][1]);
return 0;
}