题目大意: 顺次给出m个置换,反复使用这m个置换对初始序列进行操作,问k次置换后的序列。m<=10, k<2^31。
注意:
在写矩阵的乘法的时候一定要注意,写好到底是谁乘以谁。写反了就悲剧了。
还有,在求快速幂取模的时候要用非递归写法,不然容易RE;
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define Nnum 31
#define Mnum 31
#define LL long long
struct matrix
{
int n,m;
int mat[101][101];
matrix()
{
memset(mat,0,sizeof(mat));
}
matrix operator+(const matrix& B)const
{
int i,j;
matrix A;
A.n=n;
A.m=m;
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)A.mat[i][j]=mat[i][j]+B.mat[i][j];
return A;
}
}M[11];
matrix mul(matrix A,matrix B)
{
int i,j,k,nn,mm;
matrix C;
nn=A.n;
mm=B.m;
C.m=mm;
C.n=nn;
for(i=1; i<=nn; i++)
{
for(j=1; j<=mm; j++)
{
C.mat[i][j]=0;
for(k=1; k<=A.m; k++)
{
C.mat[i][j]+=A.mat[i][k]*(B.mat[k][j]);
}
}
}
return C;
}
matrix powmul(matrix A,int k)
{
matrix B;
B.n=A.n;
B.m=A.m;
for(int i=1; i<=min(B.n,B.m); i++)B.mat[i][i]=1;
while(k>=1)
{
if(k&1)B=mul(A,B);
A=mul(A,A);
k=k/2;
}
return B;
}
int main()
{
int i,j,n,m,k,a;
scanf("%d%d%d",&n,&m,&k);
memset(M,0,sizeof(M));
matrix A;
matrix ans;
A.n=A.m=n;
ans.n=n;
ans.m=1;
for(i=1; i<=n; i++)A.mat[i][i]=1,ans.mat[i][1]=i;
for(i=1; i<=m; i++)
{
M[i].n=M[i].m=n;
for(j=1; j<=n; j++)
{
scanf("%d",&a);
M[i].mat[j][a]=1;
}
A=mul(M[i],A);
}
int num=k/m;
k=k%m;
A=powmul(A,num);
for(i=1; i<=k; i++)A=mul(M[i],A);
A=mul(A,ans);
for(i=1; i<=n; i++)
{
if(i!=1)cout<<" ";
cout<<A.mat[i][1];
}
return 0;
}