Codeforces Beta Round #28 B.pSort(思维 + 并查集)
题意:
给定一个含有n个元素的数列,第i号元素开始时数值为i,元素i可以与距离为d[i]的元素进行交换。再给定一个1-n的全排列,问初始的数列可否交换成给定的样式
思路:
考虑到,如果 i 与di是在同一个连通块里,则一定可以通过交换得到目标序列
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long mod=1e9;
const int maxn=4e4+5;
int n,m,fa[maxn],de[maxn],head[maxn],nex[maxn],d,k,p[maxn],to[maxn];
void add(int x,int y){
to[++k]=y;
nex[k]=head[x];
head[x]=k;
}
int find(int x){
if(fa[x]==x)return x;
int r=x;
while(fa[x]!=r){
r=fa[x];
fa[x]=fa[r];
}
return fa[x];
}
void join(int x,int y){
int fx=find(x),fy=find(y);
if(fx==fy)return ;
if(de[fx]>de[fy])swap(fx,fy);
fa[fx]=fy;
de[fy]+=de[fx];
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)fa[i]=i,de[i]=1;
for(int i=1;i<=n;i++)
scanf("%d",&p[i]);
for(int i=1;i<=n;i++){
scanf("%d",&d);
if(i>d)join(i,i-d);
if(i+d<=n)join(i,i+d);
}
for(int i=1;i<=n;i++){
if(find(i)!=find(p[i])){
printf("NO\n");
return 0;
}
}
printf("YES\n");
}