吉首大学校赛 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个位置,每个位置可以看做一个集合. ...
随机推荐
- MySQL(关系型数据库管理系统)
MySQL 关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的 RDBMS ...
- MySQL 计算中位数
mysql中位数 奇数取中间的值,偶数取中间两个数的平均值 eg: 12345 中位数4 1234 中位数2.5 SELECT avg(t1.money) as median_val FROM ( S ...
- MySQl 截取函数 left(),right(),substring(),substring_index() 的用法
1. 字符串截取:left(str, length) mysql> select left('sqlstudy.com', 3); +-------------------------+ | l ...
- MySQL concat、concat_ws 和 group_concat 的用法
一.CONCAT()函数CONCAT()函数用于将多个字符串连接成一个字符串.使用数据表Info作为示例,其中SELECT id,name FROM info LIMIT 1;的返回结果为+----+ ...
- Linux中grep命令,用或的关系查询多个字符串,正则表达式基础说明
请尊重版权:原文:https://blog.csdn.net/lkforce/article/details/52862193 使用 grep 'word1|word2' 文件名 这样的命令是不对的 ...
- ASP.NET Core项目目录结构介绍
我们下面通过在Visual Studio 2017中创建一个空的Web应用程序来详细说明下asp.net core项目目录结构: 1.项目结构说明 (1).依赖项 这里主要分两部分SDK, 目前这两部 ...
- webstorm 插件安装
1.打勾的表示已经安装 2.没有安装的插件,可以在plugins搜索,在右边搜索结果里点install,然后重启webstorm 3.这里有常用插件 http://blog.csdn.net/xs20 ...
- 64位系统sql链接oracle
在SQL Server 2008中连接Oracle,完成查询.插入操作 建立指向Oracle的连接 在32位的系统中sql链接oracle,在链接服务器里点击服务器对象,右键链接服务器,选择micro ...
- MySQL的安装配置(无坑
简单记录一下自己掉坑无数之后,终于找到的一个不坑的方法. 一.安装 #进入一个习惯的文件夹 cd /usr/local/src #下载资源包 wget -i -c http://dev.mysql.c ...
- Django框架(二十六)—— Django rest_framework-分页器与版本控制
目录 分页器与版本控制 一.三种分页器 二.分页器 1.普通分页(PageNumberPagination) 2.偏移分页(LimitOffsetPagination) 3.加密分页(CursorPa ...