吉首大学校赛 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个位置,每个位置可以看做一个集合. ...
随机推荐
- 重磅 | 阿里云与MongoDB达成战略合作,成为全球唯一提供最新版MongoDB的云厂商
MongoDB是业界最受欢迎的开源数据库之一,2019年一份面向开发者的数据库调查报告中,MongoDB以 24.6%的使用率占据次席. 阿里云是国内最早提供MongoDB服务的云厂商,提供完全兼容M ...
- RealsenseD415/D435深度相机常用资料汇总
1.Realsense SDK 2.0 Ubuntu 16.04 安装指导网址https://github.com/IntelRealSense/librealsense/blob/master/do ...
- mysql5.6配置-my
# mkdir -p /home/mysql/3306/{data,binlog,logs} [client] port = socket=/tmp/my3306.sock [mysql] no-au ...
- windows10下安装Mysql 5.6(zip格式安装包)
5.6的安装包是一个zip文件,里面包含了data(有表空间文件和日志文件),bin等文件夹.不同于以往的只需要双击安装.msi就行了.因此,在此记录下安装包是.zip时的安装步骤. 1下载 进htt ...
- VMware 虚拟机NAT模式如何设置网络连接,从头到尾全过程~!!
一.首先查看自己的虚拟机服务有没有开启,选择电脑里面的服务查看: 1.计算机点击右键选择管理 2.进入管理选择VM开头的服务如果没有开启的话就右键开启 二.虚拟机服务开启后就查看本地网络虚拟机的网 ...
- Could not open lock file/var/lib/dpkg/lock的解决
Could not open lock file/var/lib/dpkg/lock的解决 在ubuntu系统中利用apt-get install something的时候,有时候会出现无法获得锁的权 ...
- 研究一下phpspider
官方文档 1.下载 官方github下载地址: https://github.com/owner888/phpspider 下载地址可能无法访问,这里提供一个网盘下载地址: 链接: https://p ...
- 19. HTTP协议二:HTTP请求与响应、常见状态码
HTTP请求与响应 HTTP请求 HTTP请求是指从客户端到服务器端的请求消息.HTTP请求主要由三部分构成,请求行.请求头(headers).body(请求数据). 上图是笔者用Charles抓包工 ...
- 25. SPI
- cesium左侧列表定位目标
cesium左侧列表定位目标 功能:根据左侧列表经纬度等信息的值,进行搜索定位. 列表: 1 点击清除按钮可以清空所有input的值 2 点击查找可以定位到位置,如果输入的值不在范围内,会有弹出框 ...