【BZOJ4592】[Shoi2015]脑洞治疗仪 线段树
【BZOJ4592】[Shoi2015]脑洞治疗仪
Description
Input
Output
Sample Input
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
6
6
题解:直接用线段树模拟就行,这里只说1操作。
先统计原位置有多少个have,再将原位置清空。如果能将目标位置填满,直接填满即可。否则我们需要找到应该填到哪里,即第have个空位的位置。这个可以在线段树上二分实现。
#include <cstdio>
#include <cstring>
#include <iostream>
#define lson x<<1
#define rson x<<1|1
using namespace std;
const int maxn=200010;
int n,m;
struct node
{
int sum,tag,ls,rs,sm;
node () {sum=ls=rs=sm=0,tag=-1;}
node operator + (const node &b) const
{
node c;
c.sum=sum+b.sum;
if(sum&&sum==ls&&sum==rs) c.ls=sum+b.ls;
else c.ls=ls;
if(b.sum&&b.sum==b.ls&&b.sum==b.rs) c.rs=rs+b.sum;
else c.rs=b.rs;
c.sm=max(max(sm,b.sm),rs+b.ls);
return c;
}
}s[maxn<<2];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
inline void cover(int l,int r,int x,int v)
{
if(v) s[x].tag=1,s[x].sum=s[x].ls=s[x].rs=s[x].sm=r-l+1;
else s[x].tag=s[x].sum=s[x].ls=s[x].rs=s[x].sm=0;
}
inline void pushdown(int l,int r,int x)
{
if(s[x].tag!=-1)
{
int mid=(l+r)>>1;
cover(l,mid,lson,s[x].tag),cover(mid+1,r,rson,s[x].tag),s[x].tag=-1;
}
}
void updata(int l,int r,int x,int a,int b,int c)
{
if(a>b) return ;
if(a<=l&&r<=b)
{
cover(l,r,x,c);
return ;
}
pushdown(l,r,x);
int mid=(l+r)>>1;
if(a<=mid) updata(l,mid,lson,a,b,c);
if(b>mid) updata(mid+1,r,rson,a,b,c);
s[x]=s[lson]+s[rson];
}
node query(int l,int r,int x,int a,int b)
{
if(a>b) return node();
if(a<=l&&r<=b) return s[x];
pushdown(l,r,x);
int mid=(l+r)>>1;
if(b<=mid) return query(l,mid,lson,a,b);
if(a>mid) return query(mid+1,r,rson,a,b);
return query(l,mid,lson,a,b)+query(mid+1,r,rson,a,b);
}
int find(int l,int r,int x,int a)
{
if(!a) return 0;
if(l==r) return l;
pushdown(l,r,x);
int mid=(l+r)>>1;
if(s[lson].sum>=a) return find(l,mid,lson,a);
return find(mid+1,r,rson,a-s[lson].sum);
}
int main()
{
int i,a,b,c,d,op,hav,ned;
n=rd(),m=rd();
for(i=1;i<=m;i++)
{
op=rd(),a=rd(),b=rd();
if(op==0) updata(1,n,1,a,b,1);
if(op==1)
{
c=rd(),d=rd();
hav=b-a+1-query(1,n,1,a,b).sum;
updata(1,n,1,a,b,1);
ned=query(1,n,1,c,d).sum;
if(hav>=ned) updata(1,n,1,c,d,0);
else updata(1,n,1,c,find(1,n,1,query(1,n,1,1,c-1).sum+hav),0);
}
if(op==2) printf("%d\n",query(1,n,1,a,b).sm);
}
return 0;
}//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
【BZOJ4592】[Shoi2015]脑洞治疗仪 线段树的更多相关文章
- [BZOJ4592][SHOI2015]脑洞治疗仪(线段树)
线段树基础操作题,唯一需要思考下的是将区间的前k个0覆盖为1. 线段树上二分,先递归到左子树覆盖,回溯时返回还剩多少个0未被覆盖,在根据这个信息递归到右子树.注意特判k=0的情况. 要维护的信息有:区 ...
- 【BZOJ-4592】脑洞治疗仪 线段树
4592: [Shoi2015]脑洞治疗仪 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 69 Solved: 38[Submit][Status] ...
- BZOJ 4592 SHOI2015 脑洞治疗仪 线段树
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4592 题意概述:需要维护一个01序列A,一开始A全部都是1.支持如下操作: 1.将区间[l ...
- BZOJ4592 SHOI2015脑洞治疗仪(线段树)
考虑需要资瓷哪些操作:区间赋值为0:统计区间1的个数:将区间前k个0变为1:询问区间最长全0子串.于是线段树维护区间1的个数.0的个数.最长前缀后缀全0子串即可.稍微困难的是用一个log实现将区间前k ...
- [bzoj4592] [Shoi2015]脑洞治疗仪
题面无法直视系列. 中规中矩的线段树题. 涉及的操作有:区间赋值为0,计算区间内1的个数,区间赋值为1,求区间内最大的连续的1的个数. #include<cstdio> #include& ...
- 2019.01.19 bzoj4592: [Shoi2015]脑洞治疗仪(ODT)
传送门 ODT水题. 支持区间01赋值,区间填补(把区间[l,r][l,r][l,r]从左往右数kkk个1都变成0),区间查询最长连续1个数. 思路: 区间填补操作感觉不是很好弄,写线段树的神仙可以套 ...
- bzoj 4592(洛谷 4344) [Shoi2015]脑洞治疗仪——线段树上二分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4592 1操作就是用线段树来二分找到第一个有 k 个0的位置. 在洛谷上A了,与暴力和网上题解 ...
- bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪
http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...
- 【题解】Luogu P4344 [SHOI2015]脑洞治疗仪
原题传送门:P4344 [SHOI2015]脑洞治疗仪 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看吧 珂朵莉树好题啊 我一开始一直Re65 后来重构代码就ac了,或许是rp问题 ...
随机推荐
- iTunes 无法添加 iPhone 自定义铃声
本篇文章由:http://xinpure.com/itunes-unable-to-add-iphone-custom-ringtones/ 新版本 iTunes 需要在 菜单栏 -> 文件 中 ...
- 为何 IntelliJ IDEA 比 Eclipse 更好
http://www.oschina.net/news/26929/why-intellij-is-better-than-eclipse圣战 有一些没有唯一正确答案的“永恒”的问题,例如哪个更好:是 ...
- Android给TextView设置透明背景、圆角边框
第一种方法:在drawable文件夹下新建一个文件设置背景样式 代码: 在drawable文件夹下面新建text_view_border.xml <?xml version="1.0& ...
- GCC手册学习(序)
已经是2014年的年末了,又快过了一年.今年,一定要认真把GCC再学习一遍,做好笔记. 总览 gcc [option|filename] ... g++ [option|filename] ... ...
- 实现Windows Server 2003多用户远程登录(转载)
Windows Server 2003默认情况下允许远程终端连接的数量是2个用户,我们可以根据需要适当增加远程连接同时在线的用户数. 单击“开始→运行”,输入“gpedit.msc”打开组策略编辑器窗 ...
- 【Android界面实现】View Animation 使用介绍
转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 我们能够使用view animation 动画系统来给View控件加入tween动画(下称& ...
- Redis-ha(sentinel)搭建
服务器描述:本次搭建是用来测试,所以是在一台服务器上搭建三个redis服务(一主两从) 服务角色 端口 Redis.conf名称 sentinel配置文件名称 sentinel端口 redis日志路径 ...
- Selenium操作之滚动条
在用Selenium做UI自动化时,经常会遇到有些元素找不到之类的问题,但是自己的代码并没有错,元素就是找不到,这是为什么呢?原因很简单,由于页面内容较多,有些内容需要下拉滚动条才会显示,这里介绍一种 ...
- [Delphi] 常用字符集简介
转载 http://www.cnblogs.com/yangyxd/articles/4778483.html 字符集 ANSI (ASCII)美国信息互换标准编码 GB 2312信息交换用汉字编码字 ...
- svn还原文件中去掉已经删除的文件
1.到svn目录下,选择文件并提交 2.在弹出的对话窗口中,选择文件并右击,找到"解决" 3.再次点击"还原"的时候,已经删除的文件就没有了.