RT.十分抽象。大致做法是找环,对每个环算出环内元素位置,对于环外边对其指向的环依次取值。
下面是代码。(别再回复倍增了!)
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,x[800005],y[800005],a[800005],flag[800005],flag2[800005],ss[800005],start,len,fa[800005],ans[800005],wz[800005];
vector<int>hl[800005];
long long k;
void dfs(int now){
if(flag2[now]){
start=wz[now]+1;
int siz=hl[len].size();
int ls=k%siz;
for(int j=start-1;j<siz;j++){
ans[hl[len][j]]=a[hl[len][((j+ls))%siz]];//找环
}
return ;
}
flag2[now]=1;
flag[now]=1;
hl[len].push_back(now);
ss[now]=len;
wz[now]=hl[len].size()-1;
if(!flag[x[now]]||flag2[x[now]]){
dfs(x[now]);
flag2[now]=0;
}
else{
int siz=hl[len].size(),siz2=hl[ss[x[now]]].size();
for(int i=siz-1;i>=0;i--){//顺次继承
ans[hl[len][i]]=ans[hl[ss[x[now]]][((wz[x[now]]-(siz-i))%siz2+siz2)%siz2]];
flag2[hl[len][i]]=0;
}
return ;
}
if(wz[now]==start-1){//顺次继承
int siz=wz[now],siz2=hl[ss[x[now]]].size()-wz[now];
for(int i=siz-1;i>=0;i--){
ans[hl[len][i]]=ans[hl[ss[x[now]]][start-1+((wz[x[now]]-(siz-i))%siz2+siz2)%siz2]];
flag2[hl[len][i]]=0;
}
return ;
}
return ;
}
signed main(){
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++){
scanf("%lld",&x[i]);
}
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=1;i<=n;i++){
if(!flag[i]){
start=i;
len++;
dfs(i);
}
}
for(int i=1;i<=n;i++){
printf("%lld ",ans[i]);
}
return 0;
}