zoukankan      html  css  js  c++  java
  • 【CF429E】Points and Segments

    题目

    题目链接:https://codeforces.com/problemset/problem/429/E
    有若干区间 ([l_i,r_i]),你需要把每一个区间染上黑色或白色,使得最后每一个数字被染成黑色次数与被染成白色次数的差的绝对值不超过 (1)
    (nleq 10^5)

    思路

    先把坐标离散化,考虑把所有区间扔到数组上,黑色为 (1),白色为 (-1),那么需要合理赋值颜色使得每一个点的值都是 (-1,0,1) 中的一个。
    但是这样依然不好处理,发现如果一个点被偶数个区间覆盖,那么它最终必然为 (0),否则必然为 (±1)。那么我们可以把每一个被奇数个区间覆盖的点再加上一个长度为 (1) 的区间覆盖它,然后问题转化为要求所有点的数值都变为 (0)。我们并不需要关心这个长度为 (1) 的区间的颜色,因为如果是黑色表示原本这个点的数值为 (1),白色表示原本为 (-1)
    我们再把一个区间 $[l_i,r_i] $看作一条 (l_i o r_i+1) 的边,这样转化为一张图之后,所有点数值为 (0) 就等价于“正向经过一条边为 (1),逆向经过为 (-1),任意点的所连接的边的权值之和为 (0)”。
    由于我们已经保证了所有点都被偶数个区间覆盖,也就是所有点的度数都为偶数,所以这张图必然存在欧拉回路,直接求出欧拉回路即可。
    时间复杂度 (O(nlog n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=400010;
    int n,tot=1,l[N],r[N],b[N],deg[N],head[N];
    bool vis[N];
    
    struct edge
    {
    	int next,to,tag;
    }e[N];
    
    void add(int from,int to)
    {
    	e[++tot]=(edge){head[from],to,0};
    	head[from]=tot;
    }
    
    void dfs(int x)
    {
    	vis[x]=1;
    	for (int i=head[x];~i;i=e[i].next)
    		if (!e[i].tag)
    		{
    			e[i].tag=1; e[i^1].tag=2;
    			dfs(e[i].to);
    		}
    }
    
    int main()
    {
    	memset(head,-1,sizeof(head));
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    	{
    		scanf("%d%d",&l[i],&r[i]);
    		r[i]++; b[i*2]=l[i]; b[i*2-1]=r[i];
    	}
    	sort(b+1,b+1+2*n);
    	int m=unique(b+1,b+1+2*n)-b-1;
    	for (int i=1;i<=n;i++)
    	{
    		l[i]=lower_bound(b+1,b+1+m,l[i])-b;
    		r[i]=lower_bound(b+1,b+1+m,r[i])-b;
    		add(l[i],r[i]); add(r[i],l[i]);
    		deg[l[i]]++; deg[r[i]]++;
    	}
    	for (int i=1;i<=m;i++)
    		if (deg[i]&1)
    		{
    			add(i,i+1); add(i+1,i);
    			deg[i]++; deg[i+1]++;
    		}
    	for (int i=1;i<=m;i++)
    		if (!vis[i]) dfs(i);
    	for (int i=1;i<=n;i++)
    		printf("%d ",e[i*2].tag-1);
    	return 0;
    }
    
  • 相关阅读:
    【面霸2】
    【面霸1】php知识点
    【技术宅11】php入门运算
    【技术宅10】顺序二分查找算法
    【技术宅9】遍历一个文件夹下的所有文件和子文件夹
    【技术宅7】一个或多个虚拟主机配置方法
    【技术宅6】把一个无限级分类循环成tree结构
    【技术宅5】抓去网页数据的3种方法
    【技术宅4】如何把M个苹果平均分给N个小朋友
    【技术宅3】截取文件和url扩展名的N种方法
  • 原文地址:https://www.cnblogs.com/stoorz/p/14496720.html
Copyright © 2011-2022 走看看