Description

给你一个无限长的数组,初始的时候都为0,有3种操作:

操作1是把给定区间[l,r] 设为1,

操作2是把给定区间[l,r] 设为0,

操作3把给定区间[l,r] 0,1反转。

一共n个操作,每次操作后要输出最小位置的0。

Input

第一行一个整数n,表示有n个操作

接下来n行,每行3个整数op,l,r表示一个操作

Output

共n行,一行一个整数表示答案

Sample Input

  1. 3
  2. 1 3 4
  3. 3 1 6
  4. 2 1 3

Sample Output

  1. 1
  2. 3
  3. 1

HINT

对于30%的数据1≤n≤1000,1≤l≤r≤1e18

对于100%的数据1≤n≤100000,1≤l≤r≤1e18

l,r最大可达1e18,肯定要离散化。

有大量的区间修改的操作——考虑线段树

解决方法:

离散化+线段树

首先离散化。

离散化时将每一次操作的区间的l,r,r+1放入一个数组。lower_bound离散化,得到离散化后的l,r。

为什么要放入r+1?

像这样,离散化后,1-2,3-4区间都为1,本来应该有0的存在,但在线段树上却没有,这时候就要用r+1把这个“坑”给填上。

离散化后:

线段树记录\(minn[i][0]\),\(minn[i][1]\),表示在该区间0和1最早在哪个点出现,若没出现过,minn=INF;

操作1,2: 区间修改\(minn[i][0]\),\(minn[i][1]\),\(sum[i]\)懒标记。

操作3: 交换\(minn[i][0]\),\(minn[i][1]\),\(lazy[i]\)懒标记记录是否换了回来,若没换回来,pushdown。

总体的思路就是这样了,代码有点难调试,一定要耐心打,用心调。

  1. #include<bits/stdc++.h>
  2. #define inf 1e9
  3. using namespace std;
  4. struct data
  5. {
  6. int op;
  7. long long l,r;
  8. }q[2000001];
  9. int lazy[2000001],minn[2000001][2],sum[2000001],op,n,cnt,cnt1;
  10. long long l,r,b[2000001];
  11. void build(int hao,int l,int r)
  12. {
  13. lazy[hao]=0;
  14. sum[hao]=-1;
  15. minn[hao][0]=l;
  16. minn[hao][1]=inf;
  17. if(l==r)
  18. {
  19. return;
  20. }
  21. int mid=(l+r)/2;
  22. build(hao<<1,l,mid);
  23. build(hao<<1|1,mid+1,r);
  24. }
  25. void pushdown(int hao,int l,int r)
  26. {
  27. int mid=(l+r)/2;
  28. if(sum[hao]!=-1)//下放sum
  29. {
  30. int p=sum[hao];
  31. sum[hao<<1]=sum[hao<<1|1]=p;
  32. lazy[hao<<1]=lazy[hao<<1|1]=0;
  33. minn[hao<<1][p]=l;
  34. minn[hao<<1|1][p]=mid+1;
  35. minn[hao<<1][p^1]=inf;
  36. minn[hao<<1|1][p^1]=inf;
  37. sum[hao]=-1;
  38. }
  39. if(lazy[hao])//下放lazy
  40. {
  41. lazy[hao<<1]^=1;
  42. lazy[hao<<1|1]^=1;
  43. swap(minn[hao<<1][0],minn[hao<<1][1]);
  44. swap(minn[hao<<1|1][0],minn[hao<<1|1][1]);
  45. lazy[hao]=0;
  46. }
  47. }
  48. void update(int hao,int l,int r,int L,int R,int num)//操作1,2
  49. {
  50. if(L<=l&&R>=r)
  51. {
  52. sum[hao]=num;
  53. minn[hao][num]=l;
  54. lazy[hao]=0;
  55. minn[hao][num^1]=inf;
  56. }else{
  57. pushdown(hao,l,r);
  58. int mid=(l+r)/2;
  59. if(L<=mid)
  60. {
  61. update(hao<<1,l,mid,L,R,num);
  62. }
  63. if(R>mid)
  64. {
  65. update(hao<<1|1,mid+1,r,L,R,num);
  66. }
  67. minn[hao][0]=min(minn[hao<<1][0],minn[hao<<1|1][0]);
  68. minn[hao][1]=min(minn[hao<<1][1],minn[hao<<1|1][1]);
  69. }
  70. }
  71. void change(int hao,int l,int r,int L,int R)//操作3
  72. {
  73. if(L<=l&&R>=r)
  74. {
  75. lazy[hao]^=1;
  76. swap(minn[hao][0],minn[hao][1]);
  77. }else{
  78. pushdown(hao,l,r);
  79. int mid=(l+r)/2;
  80. if(L<=mid)
  81. {
  82. change(hao<<1,l,mid,L,R);
  83. }
  84. if(R>mid)
  85. {
  86. change(hao<<1|1,mid+1,r,L,R);
  87. }
  88. minn[hao][0]=min(minn[hao<<1][0],minn[hao<<1|1][0]);
  89. minn[hao][1]=min(minn[hao<<1][1],minn[hao<<1|1][1]);
  90. }
  91. }
  92. int main()
  93. {
  94. scanf("%d",&n);
  95. for(int i=1;i<=n;i++)
  96. {
  97. scanf("%d%lld%lld",&op,&l,&r);
  98. q[i].op=op;
  99. q[i].l=l;
  100. q[i].r=r;
  101. b[++cnt]=l;
  102. b[++cnt]=r;
  103. b[++cnt]=r+1;
  104. }
  105. b[++cnt]=1;
  106. sort(b+1,b+cnt+1);
  107. b[0]=-0x7f7f7f7f;
  108. for(int i=1;i<=cnt;i++)//去重
  109. {
  110. if(b[i]==b[i-1])
  111. {
  112. continue;
  113. }
  114. b[++cnt1]=b[i];
  115. }
  116. cnt=cnt1;
  117. build(1,1,cnt);
  118. for(int i=1;i<=n;i++)
  119. {
  120. int l=lower_bound(b,b+cnt+1,q[i].l)-b;//离散化
  121. int r=lower_bound(b,b+cnt+1,q[i].r+1)-b-1;
  122. if(q[i].op==1)
  123. {
  124. update(1,1,cnt,l,r,1);
  125. }else{
  126. if(q[i].op==2)
  127. {
  128. update(1,1,cnt,l,r,0);
  129. }else{
  130. change(1,1,cnt,l,r);
  131. }
  132. }
  133. printf("%lld\n",b[minn[1][0]]);
  134. }
  135. return 0;
  136. }
  137. /*
  138. 3
  139. 1 3 4
  140. 3 1 6
  141. 2 1 3
  142. */

【XSY2484】mex的更多相关文章

  1. 【XSY2484】mex 离散化 线段树

    题目大意 给你一个无限长的数组,初始的时候都为\(0\),有3种操作: 操作\(1\)是把给定区间\([l,r]\)设为\(1\): 操作\(2\)是把给定区间\([l,r]\)设为\(0\): 操作 ...

  2. 【BZOJ3585】mex

    Description 有一个长度为n的数组{a1,a2,-,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行開始,每行一个询问l, ...

  3. 【数学】mex是什么

    最近在看博弈论,SG函数,所以什么是mex呢 然后百度了一下得到: mex(S) 的值为集合 S 中没有出现过的最小自然数.例如,mex({1,2}) = 0.mex({0,1,2,3}) = 4

  4. 【bzoj3585】mex 线段树 mex,sg

    Description 有一个长度为n的数组{a1,a2,…,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l, ...

  5. 【BZOJ3585/3339】mex 莫队算法+分块

    [BZOJ3585]mex Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. ...

  6. 【codeforces】【比赛题解】#862 CF Round #435 (Div.2)

    这次比赛打得很舒服,莫名得了个Rank41,涨了219的Rating,就比较优秀.不过还是没有闫神厉害啊.题目链接::P. [A]MEX 题意: Evil博士把Mahmoud和Ehab绑架到了邪恶之地 ...

  7. 【Luogu4137】Rmq Problem/mex (莫队)

    [Luogu4137]Rmq Problem/mex (莫队) 题面 洛谷 题解 裸的莫队 暴力跳\(ans\)就能\(AC\) 考虑复杂度有保证的做法 每次计算的时候把数字按照大小也分块 每次就枚举 ...

  8. 【HDU1848】Fibonacci again and again(博弈论)

    [HDU1848]Fibonacci again and again(博弈论) 题面 Hdu 你有三堆石子,每堆石子的个数是\(n,m,p\),你每次可以从一堆石子中取走斐波那契数列中一个元素等数量的 ...

  9. 【codeforces】940F题解

    CF Round #466的最后一题,颇有难度,正解是带修改莫队算法. [题意] 给定一个长度为\(n\)的数组\(a\),并且要求执行\(q\)个操作,有两种不同的操作: ①询问一个区间\([l,r ...

随机推荐

  1. Linux上编译安装PHP

    这篇文章主要介绍了关于Linux上编译安装PHP,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 之前在服务器上编译安装了PHP运行环境,但是安装完过了一段时间就差不多忘记了,只是零零星 ...

  2. 瀑布流实例及懒加载(echo.js)

    瀑布流布局: 图片等宽,不定高,按最低高度来顺序排列:实现方法:获取每次获取四行中最低高度对应的一行,将下一张加载的图片放在该位置,每次加载前都获取最低高度: ①请求图片的接口    地址此php文件 ...

  3. JAVA的List接口的remove重载方法调用原理

    前言 说真的,平常看源码都是自己看完自己懂,很少有写出来的冲动. 但是在写算法的时候,经常用到java中各种集合,其中也比较常用到remove方法. remove有重载函数,分别传入参数是索引inde ...

  4. [LeetCode] 470. Implement Rand10() Using Rand7()

    Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a functio ...

  5. 理解LSTM网络--Understanding LSTM Networks(翻译一篇colah's blog)

    colah的一篇讲解LSTM比较好的文章,翻译过来一起学习,原文地址:http://colah.github.io/posts/2015-08-Understanding-LSTMs/ ,Posted ...

  6. JAVA之类的动手动脑

    1.默认构造方法与自定义的构造方法的冲突 package com.xu; class fool { int value; fool(int nowvalue) { value=nowvalue; } ...

  7. Spring Boot 常用注解汇总

    一.启动注解 @SpringBootApplication @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documen ...

  8. vodevs3031 最富有的人

    在你的面前有n堆金子,你只能取走其中的两堆,且总价值为这两堆金子的xor值,你想成为最富有的人,你就要有所选择. 输入描述 Input Description 第一行包含两个正整数n,表示有n堆金子. ...

  9. cobalt strike笔记-常用beacon扫盲

    最近还是重新补一下cs的东西 0x01 Beacon命令 Beacon Commands =============== Command Description ------- ----------- ...

  10. PHP key_exists

    此函数同array_key_exsits(). 1.函数的作用:判断一个数组是否含有某个键值 2.函数的参数: @param string  $key @param array $haystack 3 ...