题目

对于两个区间\((a,b),(c,d)\),若\(c < a < d\)或\(c < b < d\)则可以从\((a,b)\)走到\((c,d)\)去,现在有以下两种操作:

  • 给定\(1 \space x \space y\),表示在集合中添加\((x,y)\)这个区间,保证新加入的这个区间一定比之前的所有区间长度长。
  • 给定\(2 \space a \space b\),表示询问是否有一条路径能从第\(a\)个区间走到第\(b\)个区间。

初始时区间集合为空,现在请你回答所有的询问

\(1 \leq n \leq 10^5,所有数字绝对值 \leq 10^9\)

题解:

容易发现新加入的区间与其左右端点落到的区间一定是可以互达的。

所以可以合并其集合。

那么对于新加入的区间所覆盖的区间来说,多了一条到新加入区间的单向边。

我们可以统计记录所有集合的最小左端点和最大右端点来判断一个区间是否可以通过有向边到达另一个区间。

对于区间的维护我们可以使用并查集。

同时使用线段树来维护插入区间和查询覆盖单点的所有区间的操作。

由于每次进行完合并操作后点上的所有的区间都会合并为一个。

所以总体复杂度\(O(n\log^2n)\)

  1. #include <vector>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. inline void read(int &x){
  8. x=0;static char ch;static bool flag;flag = false;
  9. while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
  10. while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
  11. }
  12. #define rg register int
  13. #define rep(i,a,b) for(rg i=(a);i<=(b);++i)
  14. #define per(i,a,b) for(rg i=(a);i>=(b);--i)
  15. const int maxn = 100010;
  16. int L[maxn],R[maxn],op[maxn];
  17. int c[maxn<<1],cnt = 0,fa[maxn];
  18. int find(int x){return fa[x] == x ? x : fa[x] = find(fa[x]);}
  19. inline void Union(int u,int v){
  20. int x = find(u),y = find(v);
  21. if(x == y) return ;
  22. fa[x] = y;
  23. L[y] = min(L[y],L[x]);
  24. R[y] = max(R[y],R[x]);
  25. return ;
  26. }
  27. vector<int>ve[maxn<<3];
  28. void modify(int rt,int l,int r,int p,int id){
  29. for(vector<int>::iterator it = ve[rt].begin();it != ve[rt].end();++it) Union(*it,id);
  30. if(ve[rt].empty() == false) ve[rt].clear(),ve[rt].push_back(find(id));
  31. if(l == r) return ;
  32. int mid = l+r >> 1;
  33. if(p <= mid) modify(rt<<1,l,mid,p,id);
  34. else modify(rt<<1|1,mid+1,r,p,id);
  35. }
  36. void insert(int rt,int l,int r,int L,int R,int id){
  37. if(L <= l && r <= R){ve[rt].push_back(id);return ;}
  38. int mid = l+r >> 1;
  39. if(L <= mid) insert(rt<<1,l,mid,L,R,id);
  40. if(R > mid) insert(rt<<1|1,mid+1,r,L,R,id);
  41. }
  42. int idx[maxn],num = 0;
  43. int main(){
  44. freopen("interval.in","r",stdin);
  45. freopen("interval.out","w",stdout);
  46. int n;read(n);
  47. rep(i,1,n){
  48. read(op[i]);read(L[i]);read(R[i]);
  49. if(op[i] == 1) c[++cnt] = L[i],c[++cnt] = R[i];
  50. }
  51. sort(c+1,c+cnt+1);
  52. rep(i,1,n){
  53. if(op[i] == 1){
  54. int l = lower_bound(c+1,c+cnt+1,L[i]) - c;
  55. int r = lower_bound(c+1,c+cnt+1,R[i]) - c;
  56. idx[++ num] = i;fa[i] = i;
  57. modify(1,1,cnt,l,i);modify(1,1,cnt,r,i);
  58. if(l+1 <= r-1) insert(1,1,cnt,l+1,r-1,i);
  59. }else{
  60. int u = find(idx[L[i]]);
  61. int v = find(idx[R[i]]);
  62. //printf("u = %d,v = %d\n",u,v);
  63. if(u == v) puts("YES");
  64. else if(L[v] < L[u] && L[u] < R[v]) puts("YES");
  65. else if(L[v] < R[u] && R[u] < R[v]) puts("YES");
  66. else puts("NO");
  67. }
  68. }
  69. return 0;
  70. }

「长乐集训 2017 Day1」区间 线段树的更多相关文章

  1. LOJ #6029. 「雅礼集训 2017 Day1」市场 线段树维护区间除法

    题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商 ...

  2. 【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析

    题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...

  3. 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)

    老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...

  4. loj#6029. 「雅礼集训 2017 Day1」市场(线段树)

    题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...

  5. #6029. 「雅礼集训 2017 Day1」市场 [线段树]

    考虑到每次除法,然后加法,差距会变小,于是维护加法lazytag即可 #include <cstdio> #include <cmath> #define int long l ...

  6. 「长乐集训 2017 Day10」划分序列 (二分 dp)

    「长乐集训 2017 Day10」划分序列 题目描述 给定一个长度为 n nn 的序列 Ai A_iA​i​​,现在要求把这个序列分成恰好 K KK 段,(每一段是一个连续子序列,且每个元素恰好属于一 ...

  7. loj6271 「长乐集训 2017 Day10」生成树求和 加强版(矩阵树定理,循环卷积)

    loj6271 「长乐集训 2017 Day10」生成树求和 加强版(矩阵树定理,循环卷积) loj 题解时间 首先想到先分开三进制下每一位,然后每一位分别求结果为0,1,2的树的个数. 然后考虑矩阵 ...

  8. loj #6032. 「雅礼集训 2017 Day2」水箱 线段树优化DP转移

    $ \color{#0066ff}{ 题目描述 }$ 给出一个长度为 \(n\) 宽度为 \(1\) ,高度无限的水箱,有 \(n-1\) 个挡板将其分为 \(n\) 个 \(1 - 1\) 的小格, ...

  9. loj6271「长乐集训 2017 Day10」生成树求和 加强版

    又是一个矩阵树套多项式的好题. 这里我们可以对每一位单独做矩阵树,但是矩阵树求的是边权积的和,而这里我们是要求加法,于是我们i将加法转化为多项式的乘法,其实这里相当于一个生成函数?之后如果我们暴力做的 ...

随机推荐

  1. php备份mysql数据库

    <?php /*程序功能:mysql数据库备份功能*/ ini_set('max_execution_time','0'); ini_set('memory_limit','1024M');// ...

  2. 17 南宁区域赛 F - The Chosen One 【规律】

    题目链接 https://nanti.jisuanke.com/t/19972 题意 给出一个n 然后将 n 个数 标号为 1 -> n 按顺序排列 每次抽掉 奇数位的数 然后求最后剩下那个数字 ...

  3. java 断言工具类

    1.断言工具类 package com.sze.redis.util; import java.util.Collection; import java.util.Map; import com.sz ...

  4. UnsatisfiedLinkError X.so is 64-bit instead of 32-bit之Android 64 bit SO加载机制

    http://blog.csdn.net/canney_chen/article/details/50633982 今天用户反馈应用闪退崩溃了.然后找呀找… 过程原来是这样的: 还是说下项目背景 应用 ...

  5. 网络:W5500抓包TCP segment of a reassembled PDU

    1.问题描述 W5500 http测试,用wireshark抓包,发现出现很多TCP segment of a reassembled PD. 2. 问题分析 TCP segment of a rea ...

  6. uboot相关的几篇好文

    http://www.eeworld.com.cn/mcu/2015/0727/article_21246.html http://blog.csdn.net/kernel_yx/article/de ...

  7. 【Flask】Flask-Sqlalchemy使用笔记

    ### 安装:```shellpip install flask-sqlalchemy``` ### 数据库连接:1. 跟sqlalchemy一样,定义好数据库连接字符串DB_URI.2. 将这个定义 ...

  8. PHP 面向对象及Mediawiki 框架分析(二)

    mediaHandler可以理解为处理media文件的 /includes/filerepo/file/File.php /** * Get a MediaHandler instance for t ...

  9. SQL Server获取数据库的当前连接状态

    SELECT * FROM [Master].[dbo].[SYSPROCESSES] WHERE [DBID]=(SELECT [DBID] FROM [Master].[dbo].[SYSDATA ...

  10. 如何用hexo+github搭建个人博客

    搭建环境 1.安装 Node.js: https://nodejs.org/en/ windows下点击链接,下载安装即可;Linux下更加简单,在终端下输入sudo apt-get install ...