题目大意:
对于初始序列,1,2,3,4,5 --- n 来说。给出m次变换,让你按照这样的方式的顺序执行k次。问最后得到的序列
思路分析:
0 0 1 0 1 3
1 0 0 0 2 1
0 1 0 0 * 3 = 2
0 0 0 4 4 4
所以就按照这样把左边的矩阵构造出来,然后快速幂。
模拟最后几次。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define N 30
using namespace std;
const int mod = 10007;
struct matrix
{
int a[111][111];
}origin;
int op[111][111];
int n,m,k;
matrix multiply(matrix x,matrix y)
{
matrix temp;
memset(temp.a,0,sizeof(temp.a));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
{
temp.a[i][j]+=x.a[i][k]*y.a[k][j];
// temp.a[i][j]=(temp.a[i][j])%mod;
}
}
}
return temp;
}
matrix matmod(matrix a,int k)
{
matrix res;
memset(res.a,0,sizeof res.a);
for(int i=0;i<n;i++)res.a[i][i]=1;
while(k)
{
if(k&1)
res=multiply(res,a);
k>>=1;
a=multiply(a,a);
}
return res;
}
void print(matrix x)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
printf("%d ",x.a[i][j]);
puts("");
}
printf("---------------\n");
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
matrix move,fmove;
memset(fmove.a,0,sizeof fmove.a);
for(int i=0;i<n;i++)
fmove.a[i][i]=1;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&op[i][j]);
//move.a[j][op[i][j]]=1;
}
memset(move.a,0,sizeof move.a);
for(int j=0;j<n;j++)
{
move.a[j][op[i][j]-1]=1;
}
fmove=multiply(move,fmove);
}
//print(fmove);
int time=k/m;
fmove = matmod(fmove,time);
memset(origin.a,0,sizeof origin.a);
for(int i=0;i<n;i++)
origin.a[i][0]=(i+1);
matrix ans = multiply(fmove,origin);
for(int i=0;i<(k%m);i++)
{
memset(move.a,0,sizeof move.a);
for(int j=0;j<n;j++)
move.a[j][op[i][j]-1]=1;
ans=multiply(move,ans);
}
for(int i=0;i<n;i++)
{
printf("%d%c",ans.a[i][0],i==n-1?'\n':' ');
}
}
return 0;
}