置换的开根 T^k==e,k%n==0
O(n2)
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N=1005;
int n,s;
struct Te{
int a[N];
Te(){ }
Te(int t){
if (t==1) for (int i=1;i<=n;i++) a[i]=i;
}
int &operator [](int x){
return a[x];
}
friend bool operator == (Te A,Te B){
for (int i=1;i<=n;i++) if (A[i]!=B[i]) return 0;
return 1;
}
friend Te operator * (Te A,Te B){
Te ret;
for (int i=1;i<=n;i++) ret[i]=B[A[i]];
return ret;
}
friend Te Inv(Te A){
Te ret;
for (int i=1;i<=n;i++) ret[A[i]]=i;
return ret;
}
}T;
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d%d",&n,&s);
for (int i=1;i<=n;i++) scanf("%d",&T[i]);
int ret=1,x=0;
for (int i=1;i<=n && !x;i++){
ret*=2; ret%=n;
if (ret==1) x=i;
}
s=s%x;
for (int i=s+1;i<=x;i++)
T=T*T;
for (int i=1;i<=n;i++)
printf("%d\n",T[i]);
return 0;
}
O(ns)
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N=1005;
int n,s;
struct Te{
int a[N];
Te(){ }
Te(int t){
if (t==1) for (int i=1;i<=n;i++) a[i]=i;
}
int &operator [](int x){
return a[x];
}
friend Te operator * (Te A,Te B){
Te ret;
for (int i=1;i<=n;i++) ret[i]=B[A[i]];
return ret;
}
}T,A,B;
inline Te Sqrt(Te A){
Te ret; int cur=1;
for (int i=1;i<=n;i++)
ret[cur]=A[i],cur=cur+2>n?cur+2-n:cur+2;
return ret;
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d%d",&n,&s);
for (int i=1;i<=n;i++) scanf("%d",&T[i]);
int pnt=0;
A[++pnt]=1;
while (T[A[pnt]]!=1)
A[++pnt]=T[A[pnt-1]];
for (int i=1;i<=s;i++)
A=Sqrt(A);
for (int i=1;i<n;i++)
B[A[i]]=A[i+1];
B[A[n]]=A[1];
for (int i=1;i<=n;i++)
printf("%d\n",B[i]);
return 0;
}
O(n)
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N=1005;
int n,s;
struct Te{
int a[N];
Te(){ }
Te(int t){
if (t==1) for (int i=1;i<=n;i++) a[i]=i;
}
int &operator [](int x){
return a[x];
}
friend Te operator * (Te A,Te B){
Te ret;
for (int i=1;i<=n;i++) ret[i]=B[A[i]];
return ret;
}
}T,A,B;
inline int Pow(int a,int b,int p){
int ret=1;
for (;b;b>>=1,a=a*a%p)
if (b&1)
ret=ret*a%p;
return ret;
}
inline Te Sqrt(Te A,int k){
Te ret; int cur=1;
for (int i=1;i<=n;i++)
ret[cur]=A[i],cur=cur+k>n?cur+k-n:cur+k;
return ret;
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d%d",&n,&s);
for (int i=1;i<=n;i++) scanf("%d",&T[i]);
int pnt=0;
A[++pnt]=1;
while (T[A[pnt]]!=1)
A[++pnt]=T[A[pnt-1]];
A=Sqrt(A,Pow(2,s,n));
for (int i=1;i<n;i++)
B[A[i]]=A[i+1];
B[A[n]]=A[1];
for (int i=1;i<=n;i++)
printf("%d\n",B[i]);
return 0;
}