CF429E Points and Segments

Link
把红蓝分别看成(+1,-1),然后给序列差个分,我们要做的就是给一个无向图中的边定向使得存在一条欧拉回路。因为度数可能是奇数所以补一些(0)边就行了。

#include<bits/stdc++.h>
#define N 1000007
using namespace std;
namespace IO
{
    char ibuf[(1<<21)+1],obuf[(1<<21)+1],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
    char Get() { return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++); }
    void Flush() { fwrite(obuf,1,oS-obuf,stdout),oS=obuf; }
    void Put(char x) { *oS++=x; if(oS==oT) Flush(); }
    int read(){int x=0,f=0;char ch=Get();while((ch>57||ch<48)&&ch!='-')ch=Get();if(ch=='-')f=1,ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return f? -x:x;}
}
using namespace IO;
int l[N],r[N],o[N],deg[N],head[N],ver[N],Next[N],id[N],tot=1,ans[N],vis[N],used[N];
void add(int u,int v,int num){ver[++tot]=v,Next[tot]=head[u],id[tot]=num,head[u]=tot;}
void dfs(int u)
{
    vis[u]=1;
    for(int &i=head[u];i;i=Next[i])if(!used[i])used[i]=used[i^1]=1,ans[id[i]]=(u<ver[i]),dfs(ver[i]);
}
int main()
{
    int n=read(),m=0,i,las=0;
    for(i=1;i<=n;++i) o[++m]=l[i]=read(),o[++m]=r[i]=read()+1;
    sort(o+1,o+m+1),m=unique(o+1,o+m+1)-(o+1);
    for(i=1;i<=n;++i) l[i]=lower_bound(o+1,o+m+1,l[i])-o,r[i]=lower_bound(o+1,o+m+1,r[i])-o,add(l[i],r[i],i),add(r[i],l[i],i),++deg[l[i]],++deg[r[i]];
    for(i=1;i<=m;++i) if(deg[i]&1) if(las) add(las,i,0),add(i,las,0),++deg[i],++deg[las],las=0; else las=i;
    for(i=1;i<=m;++i) if(!vis[i]) dfs(i);
    for(i=1;i<=n;++i) Put(ans[i]+'0'),Put(' ');
    return Flush(),0;
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12235542.html