吉首大学校赛 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个位置,每个位置可以看做一个集合. ...
随机推荐
- SCP-bzoj-1084
项目编号:bzoj-1084 项目等级:Safe 项目描述: 戳这里 特殊收容措施: 分类讨论+DP.#滑稽 预处理前缀和s[i][s]=Σa[j][s](∀j∈[1,i])(m=1时略去第二维) 对 ...
- Spring核心——Bean的依赖注入
依赖注入在设计模式与IoC这篇文章中,介绍了Spring基础的三大支柱的两项内容——IoC.Bean.本篇将继续围绕着Bean的创建时的注入方式来介绍Spring的核心思想与设计模式. 天底下所有面向 ...
- 【已转移】【缓存与性能优化】一篇文章搞掂:Redis
本文篇幅较长,建议合理利用右上角目录进行查看(如果没有目录请刷新). 一.什么是Redis 全称: Remote Dictionary Server 远程字典服务器 实质: 一个缓存结构服务器或数据结 ...
- Linux常用命令的使用方法
Linux 命令大全 Linux 命令大全 1.文件管理 cat chattr chgrp chmod chown cksum cmp diff diffstat file find git gitv ...
- idea 使用github
[Toc] #一.首先下载github for window 客户端,或者git客户端 这里只演示gitHub客户端,安装git客户端的话,git.exe很容易找得到. 附上网址:https://de ...
- 文件转byte[ ]
/** * 将文件转换成byte数组 * @param tradeFile * @return */public byte[] fileToByte(String fileUrl){ // 第1步.使 ...
- POJ 1052 MPI Maelstrom
MPI Maelstrom Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5547 Accepted: 3458 Des ...
- CF1215D
CF1215D 两个整数的和是偶数,他们的差也是偶数 博弈好难啊qaq 我好zz啊qaq 如果M放最后一个M胜 现在和比较大的一边如果空位还多的话M胜 M可以通过在大的那边放9来消掉那边所有的空 由于 ...
- ARM发展简史
ARM公司既不生产芯片也不销售芯片,它只出售芯片技术授权.却做到了在手持设备市场上占有90%以上的份额. 软银在2016年耗资320亿美元拿下ARM,使得本来就大红大紫的ARM公司,再一次窜到了业界人 ...
- 安装 sysbench的 报错 /usr/bin/ld: cannot find -lmysqlclient_r 解决办法
首先你需要找到这个库的位置 一般找的话需要将lib 给加上(注意:我这里是 -lmysqlclient_r 的报错,于是我找就找 libmysqlclient_r ) find / -name lib ...