首先知道p[i]≥1,所以不存在p[i]大于等于max(a,b)
用map<ll,ll>mp记录下每个p[i]出现的下标,每次找到b-p[i]或a-p[i]都进行一次连接
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int par[maxn];
int a[maxn];
int n;
map<int,int> mp;
void init(){
for (int i=0;i<=n+1;i++){
par[i]=i;//并查集初始化
}
}
int find(int x){
while(x!=par[x]){
x=par[x];
}
return x;
}//查集
void unite(int x,int y){
x=find(x);
y=find(y);
if(x!=y) par[x]=y;
}//并集
int main(){
int A,B;
cin>>n>>A>>B;
int max1=0;
for(int i=1;i<=n;i++){
cin>>a[i];
max1=max(max1,a[i]);
mp[a[i]]=i;//标记
}
if(max1>max(A,B)){
cout<<"NO"<<endl;
return 0;//这种情况不可能
}
init();
for(int i=1;i<=n;i++){
if(mp[B-a[i]])
unite(i,mp[B-a[i]]);
else unite(i,0);//如果不可能,放进特殊集合
if(mp[A-a[i]])
unite(i,mp[A-a[i]]);
else unite(i,n+1);
}
int af=find(0);
int bf=find(n+1);
if(af==bf){
//a,b集合都不可能
cout<<"NO"<<endl;
}else{
cout<<"YES"<<endl;
for(int i=1;i<=n;i++){
if(i!=1)cout<<' ';
if(af==find(i))cout<<0;
else cout<<1;
}
cout<<endl;
}
return 0;
}