http://codeforces.com/group/1EzrFFyOc0/contest/469/problem/D
题意:给n个互不相同的数以及两数a,b,有两个类A,B。
对于n个数中的任意数x,若x在A中,a-x也必在A中;若x在B中,b-x也必在B中。试问这组数满足上述条件否?若满足则输出YES,并说明第i个数属于第几类(类别用0,1表示);若不满足,则输出NO。
样例:4 5 9 YES
2 3 4 5 0 0 1 1
3 3 4 NO
1 2 4
题解:该题可用并查集解,由于x的范围过大,先用map离散化一下。
我们将类A的其中一个叶子定为n+1,类B其中一个叶子定为n+2。
对于任意的c[i]:
若a-c[i]存在,则c[i]和a-c[i]必在同一类中但不知道在哪个类中。
很好想,若c[i]在A中,则a-c[i]必须也在A中和c[i]配对;若c[i]在B中,a-c[i]若在A中,则不存在与其配对的c[i](n个数各不相同),则该情况不可能存在,即a-c[i]也在B中。
若a-c[i]不存在,则c[i]只可能在B中。
对于b-c[i]存在的讨论同理,若b-c[i]存在,则其与c[i]在同一集合,若不存在,则c[i]可能在A中。
若满足条件,A,B两棵树应该无交集,即find(n+1)!=find(n+2)。对于每个c[i],只需要看find(c[i])等于find(n+1)还是find(n+2)从而得出其在哪个类中。
若不满足,直接输出NO即可。
满足条件时:
AC代码:
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<string>
5 #include<algorithm>
6 #include<cmath>
7 #include<set>
8 #include<map>
9 #include<queue>
10 #define inf int(0x3f3f3f3f)
11 #define pi acos(-1.0)
12 #define lson l,m,rt<<1
13 #define rson m+1,r,rt<<1|1
14 #define ll long long
15 #define MAXN 100005
16 using namespace std;
17
18
19 int n,a,b;
20 int c[MAXN];
21 int fa[MAXN];
22
23 map<int,int> mp;
24
25 void Init()
26 {
27 for(int i=1;i<=n+2;i++)
28 fa[i]=i;
29 }
30
31 int findfa(int x)
32 {
33 if(fa[x]==x)return x;
34 fa[x]=fa[fa[x]];
35
36 return findfa(fa[x]);
37 }
38
39 void Unit(int x,int y)
40 {
41 x=findfa(x);
42 y=findfa(y);
43 if(x==y)return ;
44
45 fa[y]=x;
46 }
47
48
49 int main()
50 {
51 scanf("%d%d%d",&n,&a,&b);
52
53 for(int i=1;i<=n;i++)
54 {
55 scanf("%d",&c[i]);
56 mp[c[i]]=i;//离散化
57 }
58
59 Init();
60 for(int i=1;i<=n;i++)
61 {
62 if(mp[a-c[i]])
63 Unit(mp[c[i]],mp[a-c[i]]);//同一集合中,相连接
64 else
65 Unit(mp[c[i]],n+1);//只可能在B中,踢到B树去
66
67 if(mp[b-c[i]])
68 Unit(mp[c[i]],mp[b-c[i]]);
69 else
70 Unit(mp[c[i]],n+2);//踢到A树去
71 }
72
73 //若a-c[i]与b-c[i]都不存在 则AB树相连了
74
75 if(findfa(n+1)==findfa(n+2))
76 {
77 printf("NO
");
78 return 0;
79 }
80
81 printf("YES
");
82
83 for(int i=1;i<=n;i++)
84 {
85 if(findfa(mp[c[i]])==findfa(n+1))
86 printf("1 ");
87 else if(findfa(mp[c[i]])==findfa(n+2))
88 printf("0 ");
89 else//1 2 2 1 即c[i]在A,B中都满足
90 printf("1 ");
91
92 }
93
94 return 0;
95 }