题目链接:http://codeforces.com/contest/468/problem/B
Little X has n distinct integers: p1, p2, ..., pn. He wants to divide all of them into two sets A and B. The following two conditions must be satisfied:
- If number x belongs to set A, then number a - x must also belong to set A.
- If number x belongs to set B, then number b - x must also belong to set B.
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 contains n 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 print n integers: b1, b2, ..., bn (bi equals either 0, or 1), describing the division. If bi equals to 0, then pi belongs to set A, 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.
如果x属于集合A,那么a-x属于集合A
如果x属于集合B,那么b-x属于集合B
求划分方案数,不存在输出NO.否则输出YES以及每个数所属的集合,A集合用0表示,B用1表示
题解:
一看到划分集合的第一时间就是想到并查集。在这里,如果x和a-x都存在的话,就让两者建边,否则就让x和n+1建边。同理,如果x和b-x都存在的话,就让两者建边,否则让x和n+2建边。让x和n+1建边表示x不再集合A中,和n+2建边表示x不再集合B中。最后判断有没有x既不在集合A也不在集合B中,也就是n+1和n+2在一个联通分量里了。不然的话输出就行了。
///并查集
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
int a[100256];
int arr[100256];
int f(int x)
{
int r=x;
int y,t;
while(r!=arr[r])r=arr[r];
y=x;
while(y!=r)
{
t=arr[y];
arr[y]=r;
y=t;
}
return r;
}
int main()
{
int n,x,y;
map<int,int>mp;
mp.clear();
scanf("%d%d%d",&n,&x,&y);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
mp[a[i]]=i;
}
for(int i=0; i<=n+4; i++)arr[i]=i;
for(int i=1; i<=n; i++)
{
if(mp[x-a[i]])
{
arr[f(i)]=f(mp[x-a[i]]);
}
else arr[f(i)]=f(n+1);
if(mp[y-a[i]])
{
arr[f(i)]=f(mp[y-a[i]]);
}
else arr[f(i)]=f(n+2);
}
if(f(n+1)==f(n+2))printf("NO\n");
else
{
printf("YES\n");
for(int i=1; i<=n; i++)
{
if(i==n)
printf("%d\n",f(i)==f(n+1));
else printf("%d ",f(i)==f(n+1));
}
}
return 0;
}