【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问题 ...
随机推荐
- ios8设置application badge value
在ios8中,直接设置application badge value会出错 [[UIApplication sharedApplication] setApplicationIconBadgeNumb ...
- mybatis加入条件
根据http://www.cnblogs.com/friends-wf/p/3799315.html搭建的环境 User.xml加入的 if where判断的 <!-- 根据条件查询一个用户 - ...
- Android Studio Note
1.中文乱码 很多同学都安装了Android Studio,但是发现中文是乱码,其实这个很好解决的.在IDE里点击File,选择Settings...快捷键是Ctrl+alt+s 在打开的窗口中,找到 ...
- C语言之指针基础概念
今天就写一下关于C语言指针的一些感想吧. 很多同学都搞不懂指针,我一开始也云里雾里没看懂指针,而且老师又把指针说得很难的样子.其实主要是把指针”*“的作用给弄混了,不用畏惧,细心点看就可以了. 首先简 ...
- js操作时间 加法 减法 计算 格式化时间
Date.prototype.Format = function (fmt) { var o = { "M+": this.getMonth() + 1, //月份 "d ...
- javascript常量的定义
例如可以使用 const PI = 3.14159265; 一般不推荐使用 const 关键字,因为它不是 ECMAScript 语法的一部分.当需要常量的时候一般是以命名习惯来约束的,亦即使用大写字 ...
- jms、amqp、mqtt区别与联系
消息传递作为基本通信机制已经在全世界成功运用.无论是人与人.机器与人还是机器与机器之间,消息传递一直都是唯一常用的通信方式.在双方(或更多)之间交换消息有两种基本机制. 同步消息传递 异步消息传递 同 ...
- MYSQL手工注入某日本网站
作者:ice 团队:www.anying.org 转载必须注明. E-mail:1c30day@gmail.com 经过一天的辛苦劳动下班了,实在无聊,QQ上的基友基本都挂机睡觉了.找点乐子打发时 ...
- freeswitch录音功能
首先备份/usr/local/freeswitch/conf/dialplan/default.xml . 然后vi编辑default.xml ,在 <extension name=" ...
- 通道符和xargs命令
通道符“|“:是将前一个命令的输出做为后一个命令的标准输入.注意:这里的标准输入指的是:通道符右侧命令的处理内容,也就是说左侧的标准输出不能作为右侧命令的参数,只能作为命令的处理对象. 简单讲:只有通 ...