博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ4592:[SHOI2015]脑洞治疗仪(线段树)
阅读量:7171 次
发布时间:2019-06-29

本文共 4411 字,大约阅读时间需要 14 分钟。

Description

曾经发明了自动刷题机的发明家SHTSC又公开了他的新发明:脑洞治疗仪--一种可以治疗他因为发明而日益增大的脑洞的神秘装置。
为了简单起见,我们将大脑视作一个01序列。1代表这个位置的脑组织正常工作,0代表这是一块脑洞。
1
0 1 0 0 0 1 1 1 0
脑洞治疗仪修补某一块脑洞的基本工作原理就是将另一块连续区域挖出,将其中正常工作的脑组织填补在这块脑洞中。
(所以脑洞治疗仪是脑洞的治疗仪?)
例如,用上面第8号位置到第10号位置去修补第1号位置到第4号位置的脑洞。我们就会得到:
1
1 1 1 0 0 1 0 0 0
如果再用第1号位置到第4号位置去修补第8号位置到第10号位置:
0
0 0 0 0 0 1 1 1 1
这是因为脑洞治疗仪会把多余出来的脑组织直接扔掉。
如果再用第7号位置到第10号位置去填补第1号位置到第6号位置:
1
1 1 1 0 0 0 0 0 0
这是因为如果新脑洞挖出来的脑组织不够多,脑洞治疗仪仅会尽量填补位置比较靠前的脑洞。
假定初始时SHTSC并没有脑洞,给出一些挖脑洞和脑洞治疗的操作序列,你需要即时回答SHTSC的问题:
在大脑某个区间中最大的连续脑洞区域有多大。

Input

第一行两个整数n,m。表示SHTSC的大脑可分为从1到n编号的n个连续区域。有m个操作。
以下m行每行是下列三种格式之一。
0 l r :SHTSC挖了一个从l到r的脑洞。
1 l0 r0 l1 r2 :SHTSC进行了一次脑洞治疗,用从l0到r0的脑组织修补l1到r1的脑洞。
2 l r :SHTSC询问l到r这段区间最大的脑洞有多大。
n,m <=200000,1<=l<=r<=n

Output

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

Sample Input

10 10
0 2 2
0 4 6
0 10 10
2 1 10
1 8 10 1 4
2 1 10
1 1 4 8 10
2 1 10
1 7 10 1 6
2 1 10

Sample Output

3

3
6
6

Solution

0操作区间覆盖

2操作是线段树的经典问题,维护一个区间左边连续最大值,右边连续最大值,以及全局最大值,很经典就不多说了

1操作的话我们就统计一下l0,r0之间的1的个数,然后二分在l1,r1间进行区间覆盖就好了

Code

1 #include
2 #include
3 #include
4 #define N (200000+1000) 5 using namespace std; 6 7 struct node{
int sum,cov,Lmax,Rmax,Mmax,l,r;}Segt[N<<2]; 8 int n,m,opt,l0,r0,l1,r1,Left; 9 10 node operator + (node a,node b) 11 { 12 node c; 13 c.cov=-1; c.l=a.l; c.r=b.r; 14 c.sum=a.sum+b.sum; c.Lmax=a.Lmax; c.Rmax=b.Rmax; 15 if (a.Lmax==a.r-a.l+1) c.Lmax+=b.Lmax; 16 if (b.Rmax==b.r-b.l+1) c.Rmax+=a.Rmax; 17 c.Mmax=max(a.Mmax,b.Mmax); 18 c.Mmax=max(c.Mmax,a.Rmax+b.Lmax); 19 c.Mmax=max(c.Mmax,max(c.Lmax,c.Rmax)); 20 return c; 21 } 22 23 void Build(int now,int l,int r) 24 { 25 Segt[now].cov=-1; Segt[now].l=l; Segt[now].r=r; 26 if (l==r){Segt[now].sum=1; return;} 27 int mid=(l+r)>>1; 28 Build(now<<1,l,mid); Build(now<<1|1,mid+1,r); 29 Segt[now]=Segt[now<<1]+Segt[now<<1|1]; 30 } 31 32 void Pushdown(int now,int l,int r) 33 { 34 if (Segt[now].cov!=-1) 35 { 36 int mid=(l+r)>>1; 37 Segt[now<<1].cov=Segt[now<<1|1].cov=Segt[now].cov; 38 Segt[now<<1].sum=Segt[now].cov*(mid-l+1); 39 Segt[now<<1|1].sum=Segt[now].cov*(r-mid); 40 Segt[now<<1].Lmax=Segt[now<<1].Rmax=Segt[now<<1].Mmax=(Segt[now].cov^1)*(mid-l+1); 41 Segt[now<<1|1].Lmax=Segt[now<<1|1].Rmax=Segt[now<<1|1].Mmax=(Segt[now].cov^1)*(r-mid); 42 Segt[now].cov=-1; 43 } 44 } 45 46 void Update(int now,int l,int r,int l1,int r1,int x) 47 { 48 if (l>r1 || r
>1; 58 Update(now<<1,l,mid,l1,r1,x); 59 Update(now<<1|1,mid+1,r,l1,r1,x); 60 Segt[now]=Segt[now<<1]+Segt[now<<1|1]; 61 } 62 63 node Query(int now,int l,int r,int l1,int r1) 64 { 65 if (l1<=l && r<=r1) return Segt[now]; 66 Pushdown(now,l,r); 67 int mid=(l+r)>>1; 68 if (mid>=r1) return Query(now<<1,l,mid,l1,r1); 69 if (mid+1<=l1) return Query(now<<1|1,mid+1,r,l1,r1); 70 return Query(now<<1,l,mid,l1,r1)+Query(now<<1|1,mid+1,r,l1,r1); 71 } 72 73 void Change(int now,int l,int r,int l1,int r1) 74 { 75 if (!Left || l>r1 || r
=(r-l+1)-Segt[now].sum) 77 { 78 Left-=(r-l+1)-Segt[now].sum; 79 Segt[now].sum=(r-l+1); 80 Segt[now].cov=1; 81 Segt[now].Lmax=Segt[now].Rmax=Segt[now].Mmax=0; 82 return; 83 } 84 Pushdown(now,l,r); 85 int mid=(l+r)>>1; 86 Change(now<<1,l,mid,l1,r1); Change(now<<1|1,mid+1,r,l1,r1); 87 Segt[now]=Segt[now<<1]+Segt[now<<1|1]; 88 } 89 90 int main() 91 { 92 scanf("%d%d",&n,&m); 93 Build(1,1,n); 94 for (int i=1; i<=m; ++i) 95 { 96 scanf("%d",&opt); 97 if (opt==0) 98 { 99 scanf("%d%d",&l0,&r0);100 Update(1,1,n,l0,r0,0);101 }102 if (opt==1)103 {104 scanf("%d%d%d%d",&l0,&r0,&l1,&r1);105 node now1=Query(1,1,n,l0,r0);106 node now2=Query(1,1,n,l1,r1);107 Update(1,1,n,l0,r0,0);108 if (now1.sum>=now2.r-now2.l+1) {Update(1,1,n,l1,r1,1); continue;}109 Left=now1.sum; Change(1,1,n,l1,r1);110 }111 if (opt==2)112 {113 scanf("%d%d",&l0,&r0);114 node now=Query(1,1,n,l0,r0);115 printf("%d\n",max(now.Mmax,max(now.Rmax,now.Lmax)));116 }117 }118 }

转载于:https://www.cnblogs.com/refun/p/9279201.html

你可能感兴趣的文章
技能大赛规程
查看>>
涓栫晫鐢靛奖绠€鍙测€?
查看>>
Redis入门系列之队列和发布订阅模式
查看>>
Ceph学习笔记
查看>>
unity自带的水
查看>>
LVS搭建过程中需要用到的命令-- ipvsadm
查看>>
【No.9 内存泄漏了么】
查看>>
想成为一名DBA 至少要具备哪些技术
查看>>
CentOS 编译安装php5.5, 并配制支持apach,nignx核心代码
查看>>
第3章 初探HTML
查看>>
基于S/MIME V2标准的加密和解密的控件software IP*Works! S/MIME
查看>>
mysql 备份数据库脚本
查看>>
Linux文件系统上的特殊权限
查看>>
IBM携手红帽将助力企业加快虚拟化步伐
查看>>
8.C++引用
查看>>
利用imgateaselect插件实现前端页面图片截取功能
查看>>
Java super()
查看>>
xinetd服务介绍及配置
查看>>
在Redis-Sentinel的client-reconfig-script脚本中设置VIP
查看>>
服务器资源使用情况统计--脚本
查看>>