Little X has n distinct integers: p1, p2, ..., pn. He wants to divide all of them into two setsA and B. The following two conditions must be satisfied:
- If number x belongs to set A, then number a - x must also belong to setA.
- If number x belongs to set B, then number b - x must also belong to setB.
Help Little X divide the numbers into two sets or determine that it's impossible.
The first line contains three space-separated integers n, a, b (1 ≤ n ≤ 105; 1 ≤ a, b ≤ 109). The next line containsn space-separated distinct integers p1, p2, ..., pn (1 ≤ pi ≤ 109).
If there is a way to divide the numbers into two sets, then print "YES" in the first line. Then printn integers: b1, b2, ..., bn (bi equals either 0, or 1), describing the division. Ifbi equals to0, then pi belongs to setA, otherwise it belongs to set B.
If it's impossible, print "NO" (without the quotes).
4 5 9 2 3 4 5
YES 0 0 1 1
3 3 4 1 2 4
NO
It's OK if all the numbers are in the same set, and the other one is empty.
可以用并查集的思想来处理,设置额外的两个元素n+1和n+2。使得n+1是A元素,n+2属于B集合。
//171 ms 10400 KB
#include<stdio.h>
#include<string.h>
#include<map>
using namespace std;
map<int,int>mp;
int fa[100007],s[100007];
int find(int x)
{
if(fa[x] != x)
fa[x] = find(fa[x]) ;
return fa[x] ;
}
int main()
{
int n,a,b;
while(scanf("%d%d%d",&n,&a,&b)!=EOF)
{
mp.clear();
for(int i=1; i<=n; i++)
{
scanf("%d",&s[i]);
mp[s[i]]=i;
}
for(int i=1; i<=n+2; i++)fa[i]=i;
int flag=1;
for(int i=1; i<=n; i++)
{
int x=find(i);
if(mp[a-s[i]])fa[x]=find(mp[a-s[i]]);
else fa[x]=find(n+2);
if(mp[b-s[i]])fa[find(i)]=find(mp[b-s[i]]);
else fa[find(i)]=find(n+1);
}
if(find(n+1)==find(n+2))printf("NO\n");
else
{
printf("YES\n");
for(int i=1; i<n; i++)
printf("%d ",find(i)==find(n+2));
printf("%d\n",find(n)==find(n+2));
}
}
}