给出n,m,k:
一个序列n个数,m行置换操作,要执行k次操作。
求结果序列。
把m次操作算出来,作为结果再执行k/m的次方次,相当于把m次操作合并了。
再把余数的操作算出来即可,注意move在a矩阵前面
#include<bits/stdc++.h>
#define ll int
using namespace std;
const int maxn=101; //自己看情况定义
int tmp[maxn][maxn];
struct matrix{
ll arr[maxn][maxn];
matrix operator*(matrix b){
matrix ans;
ll tmp;
for(int i=0; i<maxn; i++)
for(int j=0; j<maxn; j++){
ans.arr[i][j] = 0;
for(int k=0; k<maxn; k++){
tmp = (arr[i][k]*b.arr[k][j]);
ans.arr[i][j] = (ans.arr[i][j] + tmp);
}
}
return ans;
}
};
//矩阵快速幂
matrix quick_pow(matrix a,ll N){
matrix ans;
memset(ans.arr,0,sizeof(ans.arr));
for(int i=0; i<maxn; i++)
ans.arr[i][i] = 1;
while(N){
if(N&1)
ans = ans*a;
a = a*a;
N /= 2;;
}
return ans;
}
int main(){
int n,m,k,x;
matrix a,ma; //注意置换时ma在前
memset(a.arr,0,sizeof(a.arr));
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<n;i++)
a.arr[i][i]=1;
for(int i=0;i<m;i++){
memset(ma.arr,0,sizeof(ma.arr));
for(int j=0;j<n;j++){
scanf("%d",&x);
tmp[i][j]=x-1;
ma.arr[j][x-1]=1;
}
a=ma*a;
}
int cnt=k/m;
a=quick_pow(a,cnt);
for(int i=0;i<k%m;i++){
memset(ma.arr,0,sizeof(ma.arr));
for(int j=0;j<n;j++)
ma.arr[j][tmp[i][j]]=1;
a=ma*a;
}
int ans[maxn];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a.arr[i][j])
ans[i]=j+1;
}
}
for(int i=0;i<n;i++)
printf("%d%c",ans[i],i==n-1?'\n':' ');
return 0;
}