CF429E Points and Segments 题解

CF429E Points and Segments

思路

首先这里有一个结论是一定不会有无解的情况。

发现这种形如“绝对值不超过1”的描述,考虑建图以后跑欧拉回路去确定边的方向来确定颜色。
现在来考虑如何建模。

一个发现是被覆盖次数为偶数的点一定可以通过调整来达到合法。因此我们考虑将被覆盖次数为奇数的点统计出来。当然这些点可能会很多。但是连续的奇数点是可以被合并的,因此直接离散化一下即可。

然后我们将所有给定的区间和被覆盖次数为奇数次的点拉出来建图。由于我们是覆盖问题,因此我们令连的边的区间是左闭右开的。
然后对于每个区间 \([l,r]\)\(l\)\(r\) 连边;对于每个被覆盖次数为奇数次的点,我们令 \(i\)\(i+1\) 连边即可。

code

#include<bits/stdc++.h>
using namespace std;
const int N=4e5+7;
int n,hd[N],nxt[N],to[N],l[N],r[N],cnt=0,tmp[N],d[N],idcnt=-1,vis[N],ans[N];
void add(int u,int v){nxt[++idcnt]=hd[u];to[idcnt]=v;hd[u]=idcnt;}
void dfs(int u){
    vis[u]=1;
    for(int &i=hd[u];i!=-1;i=nxt[i]){
        if(ans[i]==-1){
            ans[i]=ans[i^1]=(i&1);dfs(to[i]);
        }
    }
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n;for(int i=1;i<=n;i++){cin>>l[i]>>r[i];r[i]++;tmp[++cnt]=l[i],tmp[++cnt]=r[i];}
    sort(tmp+1,tmp+cnt+1);cnt=unique(tmp+1,tmp+cnt+1)-(tmp+1);
    for(int i=1;i<=cnt;i++) hd[i]=-1;
    for(int i=1;i<=n;i++){
        l[i]=lower_bound(tmp+1,tmp+cnt+1,l[i])-tmp;r[i]=lower_bound(tmp+1,tmp+cnt+1,r[i])-tmp;
        add(l[i],r[i]),add(r[i],l[i]);d[l[i]]++,d[r[i]]--;//这个东西是在判断奇数的区间
    }
    for(int i=1;i<=cnt;i++){d[i]+=d[i-1];if(d[i]&1) add(i,i+1),add(i+1,i);}
    for(int i=0;i<=idcnt;i++) ans[i]=-1;
    for(int i=1;i<=cnt;i++) if(!vis[i])dfs(i);
    for(int i=1;i<=n;i++) cout<<ans[(i-1)*2]<<' ';
    return 0;
}
posted @ 2025-05-29 11:15  all_for_god  阅读(107)  评论(0)    收藏  举报