solve:其实置换可以最后再操作,我们可以先合并m个操作矩阵(做乘法,乘法顺序注意一下)然后最后k%m算出剩余还要做的矩阵就行了
#pragma GCC optimize("O3") #include <bits/stdc++.h> using namespace std; #define ll long long #define re register #define pb push_back #define fi first #define se second const int N=1e6+10; const int mod=1e9+7; void read(int &a) { a=0;int d=1;char ch; while(ch=getchar(),ch>'9'||ch<'0') if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48); a*=d; } struct note { int a[105][105]; }ans,a,b[15]; int n,m,k; note mul(note x,note y) { note c; for(re int i=1;i<=n;i++) { for(re int j=1;j<=n;j++) { c.a[i][j]=0; for(re int k=1;k<=n;k++) c.a[i][j]=(c.a[i][j]+x.a[i][k]*y.a[k][j]); } } return c; } note quickmod(note x,int y) { note res,base=x; for(re int i=1;i<=n;i++) for(re int j=1;j<=n;j++) res.a[i][j]=i==j?1:0; while(y) { if(y&1) res=mul(res,base); base=mul(base,base); y>>=1; } return res; } int main() { read(n),read(m),read(k); for(re int i=1;i<=n;i++) for(re int j=1;j<=n;j++) a.a[i][j]=i==j?1:0; for(re int i=1;i<=n;i++) ans.a[i][1]=i; for(re int i=1;i<=m;i++) { note c; for(re int j=1;j<=n;j++) for(re int k=1;k<=n;k++) c.a[j][k]=0; for(re int j=1,x;j<=n;j++) read(x),c.a[j][x]=1; b[i]=c; a=mul(c,a); } int t=k/m; ans=mul(quickmod(a,t),ans); t=k%m; for(re int i=1;i<=t;i++) ans=mul(b[i],ans); for(re int i=1;i<=n;i++) printf("%d ",ans.a[i][1]); return 0; }