#2037. 「SHOI2015」脑洞治疗仪

 

题目描述

曾经发明了自动刷题机的发明家 SHTSC 又公开了他的新发明:脑洞治疗仪——一种可以治疗他因为发明而日益增大的脑洞的神秘装置。

为了简单起见,我们将大脑视作一个 01 序列。111 代表这个位置的脑组织正常工作,000 代表这是一块脑洞。

1 0 1 0 0 0 1 1 1 0

脑洞治疗仪修补某一块脑洞的基本工作原理就是将另一块连续区域挖出,将其中正常工作的脑组织填补在这块脑洞中。(所以脑洞治疗仪是脑洞的治疗仪?)

例如,用上面第 888 号位置到第 101010 号位置去修补第 111 号位置到第 444 号位置的脑洞,我们就会得到:

1 1 1 1 0 0 1 0 0 0

如果再用第 111 号位置到第 444 号位置去修补第 888 号位置到第 101010 号位置:

0 0 0 0 0 0 1 1 1 1

这是因为脑洞治疗仪会把多余出来的脑组织直接扔掉。

如果再用第 777 号位置到第 101010 号位置去填补第 111 号位置到第 666 号位置:

1 1 1 1 0 0 0 0 0 0

这是因为如果新脑洞挖出来的脑组织不够多,脑洞治疗仪仅会尽量填补位置比较靠前的脑洞。

假定初始时 SHTSC 并没有脑洞,给出一些挖脑洞和脑洞治疗的操作序列,你需要即时回答 SHTSC 的问题:在大脑某个区间中最大的连续脑洞区域有多大。

输入格式

第一行两个整数 nnn、mmm,表示 SHTSC 的大脑可分为从 111 到 nnn 编号的 nnn 个连续区域,有 mmm 个操作。

以下 mmm 行每行是下列三种格式之一:

  • 0lr0\quad l\quad r0lr:SHTSC 挖了一个范围为 [l,r][l, r][l,r] 的脑洞。
  • 1l0r0l1r11\quad l_0\quad r_0\quad l_1\quad r_11l​0​​r​0​​l​1​​r​1​​:SHTSC 进行了一次脑洞治疗,用从 l0l_0l​0​​ 到 r0r_0r​0​​ 的脑组织修补 l1l_1l​1​​ 到 r1r_1r​1​​ 的脑洞。
  • 2lr2\quad l\quad r2lr:SHTSC 询问 [l,r][l, r][l,r] 区间内最大的脑洞有多大。

上述区间均在 [1,n][1, n][1,n] 范围内。

输出格式

对于每个询问,输出一行一个整数,表示询问区间内最大连续脑洞区域有多大。

样例

样例输入

  1. 10 10
  2. 0 2 2
  3. 0 4 6
  4. 0 10 10
  5. 2 1 10
  6. 1 8 10 1 4
  7. 2 1 10
  8. 1 1 4 8 10
  9. 2 1 10
  10. 1 7 10 1 6
  11. 2 1 10

样例输出

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

数据范围与提示

对于 20%20\%20% 的数据,n,m≤100n, m \leq 100n,m≤100;
对于 50%50\%50% 的数据,n,m≤20000n, m \leq 20000n,m≤20000;
对于 100%100\%100% 的数据,n,m≤200000n, m \leq 200000n,m≤200000。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define maxn 200010
  5. using namespace std;
  6. int n,m,a[maxn];
  7. int main(){
  8. freopen("Cola.txt","r",stdin);
  9. scanf("%d%d",&n,&m);
  10. for(int i=;i<=n;i++)a[i]=;
  11. int l,r,l1,r1,l2,r2,op;
  12. while(m--){
  13. scanf("%d",&op);
  14. if(op==){
  15. scanf("%d%d",&l,&r);
  16. for(int i=l;i<=r;i++)a[i]=;
  17. }
  18. else if(op==){
  19. scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
  20. int cnt=;
  21. for(int i=l1;i<=r1;i++){
  22. cnt+=a[i];
  23. a[i]=;
  24. }
  25. for(int i=l2;i<=r2;i++){
  26. if(cnt==)break;
  27. if(a[i]==)a[i]=,cnt--;
  28. }
  29. }
  30. else {
  31. scanf("%d%d",&l,&r);
  32. int ans=,cnt=;
  33. for(int i=l;i<=r;i++){
  34. if(a[i]==)cnt++;
  35. else cnt=;
  36. ans=max(ans,cnt);
  37. }
  38. printf("%d\n",ans);
  39. }
  40. }
  41. return ;
  42. }

50分 暴力

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define maxn 200010
  6. using namespace std;
  7. struct node{int l,r,sum,ans,sz;}tr[*maxn];
  8. int tag[maxn*];
  9. void tagit(int k,int d){
  10. if(d==){
  11. tr[k].l=tr[k].r=tr[k].ans=tr[k].sz;
  12. tr[k].sum=;
  13. }
  14. else {
  15. tr[k].l=tr[k].r=tr[k].ans=;
  16. tr[k].sum=tr[k].sz;
  17. }
  18. tag[k]=d;
  19. }
  20. node update(node l,node r) {
  21. node ans;
  22. ans.l=l.l+(l.sum==?r.l:);
  23. ans.r=r.r+(r.sum==?l.r:);
  24. ans.sz=l.sz+r.sz;
  25. ans.sum=l.sum+r.sum;
  26. ans.ans=max(l.r+r.l,max(l.ans,r.ans));
  27. return ans;
  28. }
  29. void release(int k) {
  30. if (tag[k]!=-) {
  31. int d=tag[k];
  32. tag[k]=-;
  33. tagit(k<<,d);
  34. tagit(k<<|,d);
  35. }
  36. }
  37. void build(int k,int l,int r){
  38. tr[k].l=tr[k].r=tr[k].ans=;
  39. tr[k].sz=tr[k].sum=r-l+;
  40. tag[k]=-;
  41. if(l==r)return;
  42. int mid=(l+r)>>;
  43. build(k<<,l,mid);build(k<<|,mid+,r);
  44. }
  45. void modify_0(int k,int l,int r,int opl,int opr){
  46. if(l>=opl&&r<=opr){
  47. tagit(k,);
  48. return;
  49. }
  50. release(k);
  51. int mid=(l+r)>>;
  52. if(opl<=mid)modify_0(k<<,l,mid,opl,opr);
  53. if(opr>mid)modify_0(k<<|,mid+,r,opl,opr);
  54. tr[k]=update(tr[k<<],tr[k<<|]);
  55. }
  56. int modify_1(int k,int l,int r,int opl,int opr,int i){
  57. if(l>=opl&&r<=opr){
  58. int t=tr[k].sz-tr[k].sum;
  59. if(t<=i){
  60. tagit(k,);
  61. return t;
  62. }
  63. release(k);
  64. int mid=(l+r)>>;
  65. int p=modify_1(k<<,l,mid,opl,opr,i);
  66. if(p<i)p+=modify_1(k<<|,mid+,r,opl,opr,i-p);
  67. tr[k]=update(tr[k<<],tr[k<<|]);
  68. return p;
  69. }
  70. release(k);
  71. int mid=(l+r)>>,t=;
  72. if(opr<=mid)t=modify_1(k<<,l,mid,opl,opr,i);
  73. else if(opl>mid)t=modify_1(k<<|,mid+,r,opl,opr,i);
  74. else {
  75. t=modify_1(k<<,l,mid,opl,opr,i);
  76. if(t<i)t+=modify_1(k<<|,mid+,r,opl,opr,i-t);
  77. }
  78. tr[k]=update(tr[k<<],tr[k<<|]);
  79. return t;
  80. }
  81. node query(int k,int l,int r,int opl,int opr){
  82. if(l>=opl&&r<=opr)return tr[k];
  83. release(k);
  84. int mid=(l+r)>>;
  85. if(opr<=mid)return query(k<<,l,mid,opl,opr);
  86. else if(opl>mid)return query(k<<|,mid+,r,opl,opr);
  87. else return update(query(k<<,l,mid,opl,opr),query(k<<|,mid+,r,opl,opr));
  88. }
  89. int main(){
  90. freopen("Cola.txt","r",stdin);
  91. int n,m;
  92. scanf("%d%d",&n,&m);
  93. build(,,n);
  94. while(m--){
  95. int op;scanf("%d",&op);
  96. if(op==){
  97. int l,r;
  98. scanf("%d%d",&l,&r);
  99. modify_0(,,n,l,r);
  100. }
  101. else if(op==){
  102. int l0,r0,l1,r1;
  103. scanf("%d%d%d%d",&l0,&r0,&l1,&r1);
  104. node x=query(,,n,l0,r0);
  105. modify_0(,,n,l0,r0);
  106. if(x.sum)modify_1(,,n,l1,r1,x.sum);
  107. }
  108. else {
  109. int l,r;
  110. scanf("%d%d",&l,&r);
  111. node x=query(,,n,l,r);
  112. printf("%d\n",x.ans);
  113. }
  114. }
  115. return ;
  116. }

100分 线段树

loj #2037. 「SHOI2015」脑洞治疗仪的更多相关文章

  1. 【LOJ】#2037. 「SHOI2015」脑洞治疗仪

    题解 维护区间内1的个数,左边数0的长度,右边数0的长度,区间内0区间最长个数,覆盖标记 第一种操作区间覆盖0 第二种操作查询\([l_0,r_0]\)中1的个数,区间覆盖0,然后覆盖时找到相对应的区 ...

  2. LibreOJ #2037. 「SHOI2015」脑洞治疗仪

    线段树区间合并问题 恶心... 屠龙宝刀点击就送 #include <cstdio> #define N 200005 struct Segment { int l,r,mid,sum,l ...

  3. loj#2038. 「SHOI2015」超能粒子炮・改

    题目链接 loj#2038. 「SHOI2015」超能粒子炮・改 题解 卢卡斯定理 之后对于%p分类 剩下的是个子问题递归 n,k小于p的S可以预处理,C可以卢卡斯算 代码 #include<c ...

  4. [LOJ 2039] 「SHOI2015」激光发生器

    [LOJ 2039] 「SHOI2015」激光发生器 链接 链接 题解 分为两个部分 第一个是求直线之间的交点找到第一个触碰到的镜面 第二个是求直线经过镜面反射之后的出射光线 第一个很好做,第二个就是 ...

  5. Loj #2036. 「SHOI2015」自动刷题机

    link : https://loj.ac/problem/2036 这个显然具有单调性,N小的话更容易A题,不仅因为A一次题减少的代码,并且A题的下限也低. 所以直接上二分就行了,注意上限一定不要设 ...

  6. LOJ#2039. 「SHOI2015」激光发生器(计算几何)

    题面 传送门 题解 如果我初中科学老师知道我有一天计算的时候入射角不等于反射角不知道会不会把我抓起来打一顿-- 这题本质上就是个模拟,需要的芝士也就计蒜几盒的那点,不过注意细节很多,放到考场上只能看看 ...

  7. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  8. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  9. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

随机推荐

  1. [转载]Linux内核list_head学习(二)

    前一篇文章讨论了list_head 结构的基本结构和实现原理,本文主要介绍一下实例代码. 自己如果想在应用程序中使用list_head 的相应操作(当然应该没人使用了,C++ STL提供了list 用 ...

  2. Java-API:java.lang百科

    ylbtech-Java-API:java.lang百科 java.lang是提供利用 Java 编程语言进行程序设计的基础类.最重要的类是Object(它是类层次结构的根)和 Class(它的实例表 ...

  3. XXXAction-validation.xml文件中报错:Referenced file Contains errors

    我们需要引用与验证器配置相关的dtd文件,这个文件可以在xwork-core-2.3.1.2.jar下找到(xwork-validator-1.0.3.dtd) 网上有很多处理办法,如下所示: 1.直 ...

  4. 【转】火狐浏览器中firebug插件的时间线域解释

      又到了上图时间了..对照这张图,各个时间所对应的意义就很简单明了.   阻挡(Blocking):每个浏览器有并发连接数量的上限(例如Firefox对每个host限制6个连接),如果当前建立的连接 ...

  5. oracle 远程tns配置

    BYRUIY = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = rui-oracle11g)(PORT = )) (CONNECT_DATA = ...

  6. spring @Resource与@Autowired注解详解

    具有依赖关系的Bean对象,利用下面任意一种注解都可以实现关系注入: 1)@Resource (默认首先按名称匹配注入,然后类型匹配注入) 2)@Autowired/@Qualifier (默认按类型 ...

  7. 部署和调优 2.2 squid反向代理

    配置反向代理 打开配置文件 vim /etc/squid/squid.conf 修改 http_port 改为 http_port 80 accel vhost vport 在它下面添加一段 cach ...

  8. Mysql如何将一张表重复数据删除

    MySQL无法select 和 delete,update同时进行 只有将group By 出来不重复的数据进行insert到一张和之前同样类型的新表里面 转换思路,解决问题!​​

  9. 2.2.3 Analyzing the output 分析对用户推荐书目的结果(2)

    2.2.3 Analyzing the output   在之前的程序运行结果中我们得到的结果输出是: RecommendedItem [item:104, value:4.257081]   程序要 ...

  10. appium如何连接模拟器代码实例

    from appium import webdriver def connect(self): self.desired_caps = {} self.desired_caps['platformNa ...