【CF429E】Points and Segments(歐拉回路)
阿新 • • 發佈:2019-03-02
次數 sort ont 其他 pro problems get 但是 題解 。
那麽這個問題就解決完了。
還是註意即是這樣子連完了邊還可能不連通,所以每個連通塊都要跑一遍。
【CF429E】Points and Segments(歐拉回路)
題面
CF
洛谷
題解
歐拉回路有這樣一個性質,如果把所有點在平面內排成一行,路徑看成區間的覆蓋,那麽每個點被從左往右的覆蓋次數等於從右往左的覆蓋次數。
發現這題很類似上面這個東西。
將\(L\)向\(R+1\)連邊,但是不能直接做歐拉回路,因為圖不連通。
找到度數為奇數的所有點,把相鄰的兩個兩兩配對,然後在他們之間連條邊,然後求解歐拉回路。
因為這樣子配對完之後新增的區間不交,令黑色區間為\(+1\),白色區間為\(-1\),那麽除了相鄰兩個奇度數點之間的區間外,其他區間的權值和為\(0\),而奇度數之間的區間的絕對值為\(1\)
那麽這個問題就解決完了。
還是註意即是這樣子連完了邊還可能不連通,所以每個連通塊都要跑一遍。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define MAX 400100 inline int read() { int x=0;bool t=false;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x; } int n,L[MAX],R[MAX]; int S[MAX],top; struct Line{int v,next;}e[MAX]; int h[MAX],cnt=2,dg[MAX]; inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;dg[v]+=1;} int vis[MAX];bool book[MAX]; void dfs(int u) { for(int &i=h[u];i;i=e[i].next) { int v=e[i].v,j=i;if(book[i>>1])continue; book[i>>1]=true;dfs(v);vis[j>>1]=u<v; } } int main() { n=read(); for(int i=1;i<=n;++i)L[i]=read(),R[i]=read(); for(int i=1;i<=n;++i)S[++top]=L[i],S[++top]=L[i]-1; for(int i=1;i<=n;++i)S[++top]=R[i],S[++top]=R[i]+1; sort(&S[1],&S[top+1]);top=unique(&S[1],&S[top+1])-S-1; for(int i=1;i<=n;++i)L[i]=lower_bound(&S[1],&S[top+1],L[i])-S; for(int i=1;i<=n;++i)R[i]=lower_bound(&S[1],&S[top+1],R[i])-S; for(int i=1;i<=n;++i)Add(L[i],R[i]+1),Add(R[i]+1,L[i]); for(int i=1,lst=0;i<=top;++i)if(dg[i]&1)lst?Add(i,lst),Add(lst,i),lst=0:lst=i; for(int i=2;i<cnt;i+=2)if(!book[i>>1])dfs(e[i].v); for(int i=1;i<=n;++i)printf("%d ",vis[i]); return 0; }
【CF429E】Points and Segments(歐拉回路)