A - Points and Segments CodeForces - 429E
题解:
方法非常巧妙的一道题
首先考虑要求全部为0怎么做
发现是个欧拉回路的问题(很巧妙)
直接dfs一遍就可以了
而这道题
要求是-1,1,0
我们可以先离散化
完了之后判断每个点被奇数还是偶数条边覆盖
如果是奇数,那么就多连一条边
另外有个细节是为了要用欧拉回路区间左开右闭
代码:
#include <bits/stdc++.h> using namespace std; const int N=4e5; const int INF=1e9+10; int n,cnt[N],rd[N],b[N],head[N],l1; struct re{ int a,b,c,w; }a[N],e[N*2]; bool cmp(re x,re y) { return(x.a<y.a); } void arr(int x,int y) { e[++l1].a=head[x]; e[l1].b=y; head[x]=l1; e[l1].c=1; rd[x]++; } void dfs(int x) { int u=head[x]; while (u) { int v=e[u].b; if (e[u].c) { e[u].c=0; e[((u-1)^1)+1].c=0; if (x<v) e[u].w=1; else e[u].w=0; e[((u-1)^1)+1].w=e[u].w; dfs(v); } u=e[u].a; } } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); cin>>n; for (int i=1;i<=n;i++) { int li,ri; cin>>li>>ri; a[i*2-1].a=li; a[i*2].a=ri; a[i*2-1].b=i*2-1; a[i*2].b=i*2; } sort(a+1,a+n*2+1,cmp); a[0].a=-INF; int l=0; for (int i=1;i<=n*2;i++) { if (a[i].a!=a[i-1].a) if (a[i].a==a[i-1].a+1) l++; else l+=2; b[a[i].b]=l; } for (int i=1;i<=n;i++) cnt[b[i*2-1]]++,cnt[b[i*2]+1]--; int ans=0; for (int i=1;i<=l;i++) { ans+=cnt[i]; if (ans%2) arr(i,i+1),arr(i+1,i); } int l2=l1+1; for (int i=1;i<=n;i++) arr(b[i*2-1],b[i*2]+1),arr(b[i*2]+1,b[i*2-1]); for (int i=1;i<=l;i++) if (rd[i]%2) { cout<<"-1"; exit(0); } for (int i=1;i<=l+1;i++) { dfs(i); } while (l2<=l1) { cout<<e[l2].w<<" "; l2+=2; } return 0; }