快哭晕了。。。。自己简直是作死作到不能再死。。。。
他说是2-SAT。。。看了题就用2-SAT敲。。。。最后交一发。。。居然WA在TEST1。。。。。然后没时间了= =。。。今天发现输出0,1哪里位运算打反了。。。。(<<1打成了>>1.。。)。。。
A表示在A集合,A'表示在B集合。。。。
把输入的数用map存下,并标号。。。然后再遍历一遍输入的数。
aa=a-x[i],bb=b-x[i]..如果能在map中找打aa,说明输入了aa,所以当前x[i]在集合B的话,aa就一定在集合B,aa在集合A,x[i]就一定要在集合A。。。就是A'-B',B-A(A表示x[i],B表示aa)不存在就x[i]一定在集合A。。A'-A..
在map中能找到bb,x[i]在集合A,bb就一定在集合A,bb在集合B,x[i]就一定在集合B,就是A-B,B'-A',同理不存在x[i]在集合B。。A-A'。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<string>
#include<map>
#include<vector>
#define ll __int64
using namespace std;
const int MAXN=200010;
vector<int> G[MAXN];
map<ll,int> mp;
int x[MAXN];
int sccno[MAXN],low[MAXN],pre[MAXN],sc_cnt,dfs_clock;
stack<int> S;
void init()
{
memset(pre,0,sizeof(pre));
memset(sccno,0,sizeof(sccno));
sc_cnt=dfs_clock=0;
}
void tarjan(int u)
{
low[u]=pre[u]=++dfs_clock;
S.push(u);
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!pre[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!sccno[v])
low[u]=min(low[u],pre[v]);
}
if(low[u]==pre[u])
{
sc_cnt++;
while(1)
{
int x=S.top();
S.pop();
sccno[x]=sc_cnt;
if(x==u)
break;
}
}
}
bool find_sc(int n)
{
init();
for(int i=0;i<2*n;i++)
{
if(!pre[i])
tarjan(i);
}
for(int i=0;i<n;i++)
{
if(sccno[i<<1]==sccno[i<<1|1])
return 0;
}
return 1;
}
int main()
{
int n,a,b,i,j;
string s1;
while(scanf("%d%d%d",&n,&a,&b)==3)
{
mp.clear();
for(i=0;i<=2*n;i++)
G[i].clear();
for(i=0;i<n;i++)
{
scanf("%d",&x[i]);
mp[x[i]]=i;
}
for(i=0;i<n;i++)
{
int aa=a-x[i];
int bb=b-x[i];
if(mp.count(aa))
{
int k=mp[aa];
G[i<<1|1].push_back(k<<1|1);
G[k<<1].push_back(i<<1);
}
else
{
G[i<<1|1].push_back(i<<1);
}
if(mp.count(bb))
{
int k=mp[bb];
G[i<<1].push_back(k<<1);
G[k<<1|1].push_back(i<<1|1);
}
else
{
G[i<<1].push_back(i<<1|1);
}
}
bool flag=find_sc(n);
if(flag)
{
printf("YES\n");
for(i=0;i<n;i++)
{
if(sccno[i<<1]>=sccno[i<<1|1])
{
printf("0");
}
else
printf("1");
if(i!=n-1)
printf(" ");
else
printf("\n");
}
}
else
printf("NO\n");
}
return 0;
}