吉首大学校赛 K 白山茶与红玫瑰 (线段树区间操作)
链接:https://ac.nowcoder.com/acm/contest/925/K
来源:牛客网
题目描述
输入描述:
输出描述:
对于每一次op=0的操作,输出区间内连续最多的白山茶战士数目。
说明
0 1 4 : answer=1
1 2 3 : 1 1 0 0
0 1 4 : answer=2
1 3 3 : 1 1 1 0
0 4 4 : answer=0 题意:首先有一个序列,只有 0 和 1组成,有两种操作
1:把区间内的所有值全部翻转,0变1,1变0
0:输出区间内最长的连续1 思路:这一看就是经典的线段树问题
1,首先解决翻转问题,我们只要记录区间内有多少个0,有多少个1,然后我们翻转的时候交换两个值即可
2,输出最长的连续1,这个我们就要记录三个值,前缀最长连续1,后缀最长连续1,然后合并的时候就是左子树的最长连续1和右子树的最长连续1,或者是左子树
后缀+右子树前缀,这个就能得到了,这里为了我们考虑翻转问题,所有我们还要同时记录前缀0和后缀0,这样后面也是找出交换
然后就是些细节问题了,注意查询的时候我们如果涉及两个区间我们要考虑左子树的最长连续1,右子树的最长连续1,左子树的后缀1+右子树的前缀1三个的最大值
还有push_up的时候,前缀1和后缀1要考虑满树的情况
例如 左子树前缀1如果满了的话,就要加上右子树的前缀才是父亲节点的前缀
#include<bits/stdc++.h>
#define mod 1000000007
#define pi acos(-1)
#define eps 1e-9
using namespace std;
typedef long long ll;
const int maxn = ;
struct sss
{
ll l,r;
ll z1,y1;
ll z0,y0;
ll mx1,mx0;
ll cnt;
}tree[*maxn];
ll n,a[maxn]; void push_up(ll rt){
int mid=tree[rt].l+tree[rt].r>>;
tree[rt].mx0=max(tree[rt<<].mx0,tree[rt<<|].mx0);
tree[rt].mx0=max(tree[rt].mx0,tree[rt<<].y0+tree[rt<<|].z0);
tree[rt].mx1=max(tree[rt<<].mx1,tree[rt<<|].mx1);
tree[rt].mx1=max(tree[rt].mx1,tree[rt<<].y1+tree[rt<<|].z1); tree[rt].z0=tree[rt<<].z0;
if(tree[rt].z0==mid-tree[rt].l+) tree[rt].z0+=tree[rt<<|].z0;
tree[rt].y0=tree[rt<<|].y0;
if(tree[rt].y0==tree[rt].r-mid) tree[rt].y0+=tree[rt<<].y0; tree[rt].z1=tree[rt<<].z1;
if(tree[rt].z1==mid-tree[rt].l+) tree[rt].z1+=tree[rt<<|].z1;
tree[rt].y1=tree[rt<<|].y1;
if(tree[rt].y1==tree[rt].r-mid) tree[rt].y1+=tree[rt<<].y1;
}
void build(ll cnt,ll l,ll r){
tree[cnt].l=l;
tree[cnt].r=r;
if(l==r){
if(a[l]==){
tree[cnt].z0=;
tree[cnt].y0=;
tree[cnt].mx0=;
}
else{
tree[cnt].mx1=;
tree[cnt].z1=;
tree[cnt].y1=;
}
return;
}
ll mid=(l+r)/;
build(cnt*,l,mid);
build(cnt*+,mid+,r);
push_up(cnt);
}
void change(ll cnt){
tree[cnt].cnt++;
ll t=tree[cnt].z0;
tree[cnt].z0=tree[cnt].z1;
tree[cnt].z1=t; t=tree[cnt].y0;
tree[cnt].y0=tree[cnt].y1;
tree[cnt].y1=t; t=tree[cnt].mx0;
tree[cnt].mx0=tree[cnt].mx1;
tree[cnt].mx1=t;
}
void push_down(ll cnt){
tree[cnt].cnt--;
change(cnt*);
change(cnt*+);
}
ll query(ll cnt,ll l,ll r){
if(l<=tree[cnt].l&&r>=tree[cnt].r){
return tree[cnt].mx1;
}
if(tree[cnt].cnt%)
push_down(cnt);
ll mid=(tree[cnt].l+tree[cnt].r)/;
if(r<=mid){
return query(cnt*,l,r);
}
else if(l>mid){
return query(cnt*+,l,r);
}
else{
ll x=query(cnt*,l,mid);
ll y=query(cnt*+,mid+,r);
ll rlv=min(mid-l+,tree[cnt<<].y1)+min(r-mid,tree[cnt<<|].z1);
return max(x,max(y,rlv));
}
}
void update(ll cnt,ll l,ll r){
if(tree[cnt].l==l&&tree[cnt].r==r){
change(cnt);
return;
}
ll mid=(tree[cnt].l+tree[cnt].r)/;
if(tree[cnt].cnt%)
push_down(cnt);
if(r<=mid)
update(cnt*,l,r);
else if(l>mid)
update(cnt*+,l,r);
else{
update(cnt*,l,mid);
update(cnt*+,mid+,r);
}
push_up(cnt);
}
int main()
{
cin>>n;
for(int i=;i<=n;i++) cin>>a[i];
ll m,op,l,r;
build(,,n);
cin>>m;
for(int i=;i<=m;i++){
cin>>op>>l>>r;
if(op==){
cout<<query(,l,r)<<"\n";
}
else{
update(,l,r);
}
}
}
吉首大学校赛 K 白山茶与红玫瑰 (线段树区间操作)的更多相关文章
- 校赛F 比比谁更快(线段树)
http://acm.cug.edu.cn/JudgeOnline/problem.php?cid=1153&pid=5 题意:给你一个字符串,各两个操作: ch=0,[l,r]降序 ch=1 ...
- hpu校赛--雪人的高度(离散化线段树)
1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec 内存限制: 128 MB 提交: 81 解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...
- 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)
Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...
- 《白书》上线段树RMQ的实现
白书上的线段树RMQ实现,自己重写了一遍: #include <bits/stdc++.h> using namespace std; const int MAXN=1<<17 ...
- HDU5039--Hilarity DFS序+线段树区间更新 14年北京网络赛
题意:n个点的树,每个条边权值为0或者1, q次操作 Q 路径边权抑或和为1的点对数, (u, v)(v, u)算2个. M i修改第i条边的权值 如果是0则变成1, 否则变成0 作法: 我们可以求出 ...
- HDU5107---K-short Problem (线段树区间 合并、第k大)
题意:二维平面上 N 个高度为 Hi 建筑物,M次询问,每次询问输出 位于坐标(x ,y)左下角(也就是xi <= x && yi <= y)的建筑物中的第k高的建筑物的高 ...
- BZOJ3110[Zjoi2013]K大数查询——权值线段树套线段树
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...
- BZOJ 3110 [ZJOI2013]K大数查询 (整体二分+线段树)
和dynamic rankings这道题的思想一样 只不过是把树状数组换成线段树区间修改,求第$K$大的而不是第$K$小的 这道题还有负数,需要离散 #include <vector> # ...
- [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)
[BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...
随机推荐
- Spring框架-经典的案例和demo,一些可以直接用于生产,使用atomikos来处理多数据源的一致性事务等
Spring Examples Demo website:http://www.ityouknow.com/ 对Spring框架的学习,包括一些经典的案例和demo,一些可以直接用于生产. sprin ...
- eureka学习(二)
eureka服务端创建好后,现在我们让eureka客户端(也就是服务提供者)注册到eureka上去. 首先加入依赖包: <!--将微服务provider注册到eureka--> <d ...
- pycharm 代码无法自动补全(自动顺带)的解决方法
pycharm 中输入关键字等,代码不能自动补全,这种情况一般是pycharm设置了省电模式 点击 File —Power Save Mode,取消勾选 再次输入,代码可以自动顺带出来了
- jmeter之-聚合报告&分析结果
Label:请求的名称 Sample:表示这次测试中一共发了多少个请求 Average:平均响应时间 median:中位数,也就是表示在所有请求响应时间中排在中间的那个响应的时间点,50%line 实 ...
- Cent OS 7下安装 mongodb
1.下载MongoDB 安装包 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.8.tgz 2.解压并安装 .tgz 3. ...
- 线程同步(基于java)
java线程 同步与异步 线程池 1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成 ...
- ylbtech-公司-滴滴出行:滴滴出行
ylbtech-公司-滴滴出行:滴滴出行 滴滴出行是涵盖出租车. 专车. 滴滴快车. 顺风车. 代驾及 大巴等多项业务在内的一站式出行平台,2015年9月9日由“滴滴打车”更名而来. 2月1日起, ...
- PHP 代码编写注意事项总结归纳
1- 编写模块化代码 良好的PHP代码应该是模块化代码.PHP的面向对象的编程功能是一些特别强大的工 具,可以把你的应用程序分解成函数或方法.你应该尽可能多的从你的应用程序的服务器端分开前端的HTML ...
- POJ 1789 Truck History (Kruskal)
题目链接:POJ 1789 Description Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks ...
- 通过rocketmq思考一下mq的设计取舍
1. RocketMQ路由中心NameServer 2. RocketMQ消息发送 3. RocketMQ消息存储 4. RocketMQ消息消费 5. 消息过滤FiterServer 6. Rock ...