题目链接:https://codeforces.com/contest/1278/problem/D

题目大意:

给定一堆线段[li,ri],每个线段的端点都不一样,如果两个线段相交,那么他们必须是有一段相交而不是内嵌,比如[1,3]与[2,4]相交,而[1,4]与[2,3]不相交。

现在,对于每对相交的线段,我们对他们建边,比如[l1,r1]与[l2,r2]相交,1和2就可以建边,问你最后能否建成一颗树?注意只能是一棵树,任意两点之间只有一条唯一的路径。

思路:

暴力O(n^2)肯定不行,我们需要加速处理。

首先对所有区间对左端点排序,对于当前考虑的区间i,因为之前的区间左端点一定小于li,所以相交的情况只可能是前面区间的右端点落在[li,ri]这个区间里面了。而现在是问你能否构成一棵树,一棵树最多的边就是n-1,并且用并查集维护的话,最后所有的点的父亲相同。

所以我们可以在set中保存右端点信息,每次来一个新区间[li,ri],我们lower_bound寻找右端点在这个区间内的所有区间,然后暴力地建边,如果出现建的边数大于等于n,或者建边的两方已经是同一个并查集了,那肯定不行,否则就直接建边。最后再拍一遍看是否所有点都缩在同一个并查集里,就ok了。

#include <bits/stdc++.h>
using namespace std;const int maxn=1e6+10;
set<int>s;
struct Node{int l,r;
}node[maxn];
int cmp(const Node a,const Node b){return a.l<b.l;
}
int fa[maxn];
int find_set(int x){return fa[x]==x?fa[x]:fa[x]=find_set(fa[x]);
}
bool Union(int x,int y){if(x==y)return true;int fx=find_set(x),fy=find_set(y);//printf("Union %d %d\n",fx,fy);if(fx==fy)return false;if(fx<fy){fa[fy]=fx;}else{fa[fx]=fy;}return true;
}
map<int,int>mp;
signed main(){int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&node[i].l,&node[i].r);fa[i]=i;}sort(node+1,node+n+1,cmp);for(int i=1;i<=n;i++){mp[node[i].r]=i;}int sum=n;for(int i=1;i<=n;i++){int l=node[i].l,r=node[i].r;auto it=s.lower_bound(l);int cnt=0;while(it!=s.end()&&*it<r){//printf("hello %d %d\n",mp[*it],i);if(!Union(mp[*it],i)){//printf("hello %d %d\n",mp[*it],i);puts("NO");//printf("debug 1\n");return 0;}cnt++;it++;}if(sum-cnt<=0){puts("NO");//printf("debug 2\n");return 0;}sum-=cnt;s.insert(r);}for(int i=2;i<=n;i++){int f=find_set(i);if(f!=find_set(1)){puts("NO");//printf("debug 3\n");return 0;}}puts("YES");return 0;
}

Codeforces 1278 D.Segment Tree(排序+set)相关推荐

  1. codeforces EDU segment tree

    本文以codeforces EDU segment tree为资料 content introdcution problems & solutions A. Sign alternation ...

  2. Codeforces 1129 E.Legendary Tree

    Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1​\) 次 \((S=\{1\},T=\{ ...

  3. C++Persistent segment tree持久段树的实现算法(附完整源码)

    C++Persistent segment tree持久段树的实现算法 C++Persistent segment tree持久段树的实现算法完整源码(定义,实现,main函数测试) C++Persi ...

  4. C语言实现段树segment tree(附完整源码)

    C语言实现段树segment tree 段树结构体定义 实现以下6个接口 完整实现和main测试源码 段树结构体定义 typedef struct segment_tree {void *root; ...

  5. Segment Tree

    Leetcode上一道题,给定一个整数数组,要实现: 求[i, j]所有元素的和,0 <= i <= j <= n - 1,sumRange(i, j) 数组的元素会被修改, upd ...

  6. 【线段树】Segment Tree

    Segment Tree 时间限制: 1 Sec  内存限制: 512 MB 提交: 107  解决: 23 [提交] [状态] [命题人:admin] 题目描述 Mcginn opens the c ...

  7. HDURevenge of Segment Tree(第二长的递增子序列)

    HDURevenge of Segment Tree(第二长的递增子序列) 题目链接 题目大意:这题是求第二长的递增子序列. 解题思路:用n^2的算法来求LIS,可是这里还要记录一下最长的那个序列是否 ...

  8. Segment Tree Beats 区间最值问题

    Segment Tree Beats 区间最值问题 线段树一类特殊技巧! 引出:CF671C Ultimate Weirdness of an Array 其实是考试题,改题的时候并不会区间取最值,区 ...

  9. poj 2892 Tunnel Warfare (Splay Tree instead of Segment Tree)

    poj.org/problem?id=2892 poj上的一道数据结构题,这题正解貌似是Segment Tree,不过我用了Splay Tree来写,而且我个人认为,这题用Splay Tree会更好写 ...

最新文章

  1. 起飞,会了这4个 Intellij IDEA 调试魔法,阅读源码都简单了
  2. python实现vlookup功能_干货一:怎么在python里面实现vlookup
  3. 评估指标_供应链改进常用评估指标
  4. 机器学习的部分名词解释20180724
  5. arXiv 2021《Transformer in Transformer》论文笔记
  6. 每天一道LeetCode-----有效回文串
  7. bzoj2007: [Noi2010]海拔
  8. MySQL concat()函数
  9. 2017蓝桥杯省赛---java---C---7 Excel地址)
  10. 关于BigInteger的加减乘除使用
  11. JavaScript中的类方法、对象方法、原型方法
  12. 硬件?软件?视频会议系统中两者有何区别?
  13. 瑞士:冰川融化 阿尔卑斯部分山体面临坍塌
  14. 如何从超级用户进入非超级用户
  15. 百度地图KEY发布版SHA1和开发板SHA1如何获得
  16. Python就业方向都有什么?该如何选择?
  17. Android实战——简单网络视频播放器
  18. Excel应用技巧:合并单元格的排序
  19. Java 13个语法糖梳理总结
  20. 通用的一阶IIR数字高通滤波器的实现

热门文章

  1. rpm 查看依赖关系 依赖谁和被谁依赖
  2. JScrollPane的使用
  3. C语言程序课程设计—读心术
  4. 深入浅出业务幂等性---4、消息幂等
  5. Android Market api
  6. uni-app H5 上传图片
  7. oracle any 语法,Oracle:apos;= ANY()apos;与apos;IN()apos; Dovov编程网
  8. java 框架 面试常见题目
  9. 多线程—如何下载网图
  10. 微博快捷登录提示21322重定向地址不匹配(解决方案)