【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问题 ...
随机推荐
- vs2017安装过程问题及解决方法
1. 问题:C++ 无法打开 源 文件 "errno.h"等文件 解决方法:https://jingyan.baidu.com/article/8ebacdf0167b2249f6 ...
- IDEA启动服务慢的问题处理
问题描述: 微服务模式下统一启动服务,很慢如下图: 这种情况是IDEA工作环境有问题. 解决方法: 从SVN或者Git重新检出项目,即可解决.
- 转: 利用RabbitMQ、MySQL实现超大用户级别的消息在/离线收发
由于RabbitMQ中只有队列(queue)才能存储信息,所以用RabbitMQ实现超大用户级别(百万计)的消息在/离线收发需要对每一个用户创建一个永久队列. 但是RabbitMQ节点内存有限,经测试 ...
- python selenium --unittest 框架
转自:http://www.cnblogs.com/fnng/p/3300788.html 学习unittest 很好的一个切入点就是从selenium IDE 录制导出脚本.相信不少新手学习sele ...
- mysql导入慢
MySQL导出的SQL语句在导入时有可能会非常非常慢,经历过导入仅45万条记录,竟用了近3个小时.在导出时合理使用几个参数,可以大大加快导 入的速度. -e 使用包括几个VALUES列表的多行INSE ...
- log4cxx在linux下的编译使用
最近在linux下使用log4cxx库,按照其官方文档提供的方法来进行编译,不能成功,又利用google搜索了好几个中文博客上讲述在linux下编译使用log4cxx库的方法,依然不能成功,在这里我奉 ...
- Vivado的helloword程序:硬件工程部分
硬件平台:ZedBoard软件平台:vivado2013.3 本示例通过综合.实现,生成比特流,发送到SDK实现.启动vivado并且创建一个项目根据提示操作一步步创建新项目的时候记得选择RTL Pr ...
- TextView中超链接拦截
TextView中的超链接点击时,其实是通过Intent方式的,因此会调用Activity中的startActivity(Intent intent)方法,所以可在此方法中做些简单的拦截操作 例如拦截 ...
- redis命令_SETNX
SETNX key value 将 key 的值设为 value ,当且仅当 key 不存在. 若给定的 key 已经存在,则 SETNX 不做任何动作. SETNX 是『SET if Not eXi ...
- 李洪强IOS经典面试题 33-计算有多少个岛屿
李洪强IOS经典面试题 33-计算有多少个岛屿 问题 在一个地图中,找出一共有多少个岛屿. 我们用一个二维数组表示这个地图,地图中的 1 表示陆地,0 表示水域.一个岛屿是指由上下左右相连的陆地,并且 ...