题意
已知({1,2,...,n})按照(P)经过(k)次变化之后得到(A),现在给定(A)与(k),求({1,2,...,n})按照(P)经过(1)次变化之后的结果(B)。
题解
主要的知识点是置换群,当然我一点都不了解,所以这道题直接GG。
可以得知,(B^k=A),根据置换群与逆元可知,(A^{k^{-1}}=B)。设(A)中所有环是(r_1,r_2,...,r_m),本来(k^{-1})应该是(lcm{|r_1|,|r_2|,...,|r_m|})下的逆元,但其实可以对每个环分开考虑,所以对于每个环(r_i),求出(k)在模(|r_i|)下的逆元(inv_i),然后对环上每个点变换(inv_i)次就行了。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+10;
int n,a[N],ans[N],vis[N],k;
vector<int> vec;
void dfs(int u){
if(vis[u]) return;
vis[u]=1;
vec.push_back(u);
dfs(a[u]);
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int w=1;w<=n;w++){
if(vis[w]) continue;
vec.clear();
dfs(w);
int siz=vec.size(),inv;
for(int i=1;i<=siz;i++)if(1ll*k*i%siz==1) inv=i;
for(int i=0;i<siz;i++) ans[vec[i]]=vec[(i+inv)%siz];
}
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
}