吉首大学2019年程序设计竞赛(重现赛)-K(线段树)
题目链接:https://ac.nowcoder.com/acm/contest/992/K
题意:给一个大小为1e5的数组,由0 1组成,有两种操作,包括区间修改,将一段区间内的0换成1,1换成0; 区间查询,查询区间内连续1的数量。
思路:区间查询和区间修改,明显可以用线段树来做,我们先分析下复杂度,每次操作复杂度为logn,有m次操作(m<=1e5+1),那么总复杂度为mlogn,是可行的。
我们用线段树维护什么呢,因为要求区间最多连续1的个数。那么需要维护区间前缀连续0/1的个数fr[0]/fr[1],区间后缀0/1的个数ba[0]/ba[1],区间连续0/1个数最大值mx[0]/mx[1]。维护连续0的个数是因为0和1可以相互转换,这样进行更新时就方便不少。懒惰标记lazy可以用异或1来更新,因为更新两次就相当与不更新。
因为维护的元素较多,pushup和pushdown操作就稍微复杂。这题查询的方式是需要学习的,返回区间最大连续1的个数,注意考虑由左区间后缀1和右区间前缀1组合的情况。
详见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int maxn=; struct node{
int l,r,len,fr[],ba[],mx[];
int lazy;
}tr[maxn<<]; int n,m,ans,a[maxn]; void pushup(int v){
if(tr[v<<].fr[]==tr[v<<].len){
tr[v].fr[]=tr[v<<].fr[]+tr[v<<|].fr[];
tr[v].fr[]=;
}
else if(tr[v<<].fr[]==tr[v<<].len){
tr[v].fr[]=tr[v<<].fr[]+tr[v<<|].fr[];
tr[v].fr[]=;
}
else{
tr[v].fr[]=tr[v<<].fr[];
tr[v].fr[]=tr[v<<].fr[];
}
if(tr[v<<|].ba[]==tr[v<<|].len){
tr[v].ba[]=tr[v<<].ba[]+tr[v<<|].ba[];
tr[v].ba[]=;
}
else if(tr[v<<|].ba[]==tr[v<<|].len){
tr[v].ba[]=tr[v<<].ba[]+tr[v<<|].ba[];
tr[v].ba[]=;
}
else{
tr[v].ba[]=tr[v<<|].ba[];
tr[v].ba[]=tr[v<<|].ba[];
}
tr[v].mx[]=max(tr[v<<].ba[]+tr[v<<|].fr[],max(tr[v<<].mx[],tr[v<<|].mx[]));
tr[v].mx[]=max(tr[v<<].ba[]+tr[v<<|].fr[],max(tr[v<<].mx[],tr[v<<|].mx[]));
} void pushdown(int v){
tr[v<<].lazy^=,tr[v<<|].lazy^=;
swap(tr[v<<].fr[],tr[v<<].fr[]);
swap(tr[v<<].ba[],tr[v<<].ba[]);
swap(tr[v<<].mx[],tr[v<<].mx[]);
swap(tr[v<<|].fr[],tr[v<<|].fr[]);
swap(tr[v<<|].ba[],tr[v<<|].ba[]);
swap(tr[v<<|].mx[],tr[v<<|].mx[]);
tr[v].lazy=;
} void build(int v,int l,int r){
tr[v].l=l,tr[v].r=r,tr[v].len=r-l+;
if(l==r){
if(a[r]){
tr[v].fr[]=,tr[v].fr[]=;
tr[v].ba[]=,tr[v].ba[]=;
tr[v].mx[]=,tr[v].mx[]=;
}
else{
tr[v].fr[]=,tr[v].fr[]=;
tr[v].ba[]=,tr[v].ba[]=;
tr[v].mx[]=,tr[v].mx[]=;
}
return;
}
int mid=(l+r)>>;
build(v<<,l,mid);
build(v<<|,mid+,r);
pushup(v);
} void update(int v,int l,int r){
if(l<=tr[v].l&&r>=tr[v].r){
swap(tr[v].fr[],tr[v].fr[]);
swap(tr[v].ba[],tr[v].ba[]);
swap(tr[v].mx[],tr[v].mx[]);
tr[v].lazy^=;
return;
}
if(tr[v].lazy) pushdown(v);
int mid=(tr[v].l+tr[v].r)>>;
if(l<=mid) update(v<<,l,r);
if(r>mid) update(v<<|,l,r);
pushup(v);
} int query(int v,int l,int r){
if(tr[v].l==l&&tr[v].r==r)
return tr[v].mx[];
if(tr[v].lazy) pushdown(v);
int mid=(tr[v].l+tr[v].r)>>;
if(r<=mid)
return query(v<<,l,r);
else if(l>mid)
return query(v<<|,l,r);
else{
int x,y,z;
x=min(tr[v<<].ba[],mid-l+)+min(tr[v<<|].fr[],r-mid);
y=query(v<<,l,mid);
z=query(v<<|,mid+,r);
return max(x,max(y,z));
}
} int main(){
scanf("%d",&n);
for(int i=;i<=n;++i)
scanf("%d",&a[i]);
build(,,n);
scanf("%d",&m);
while(m--){
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==)
update(,x,y);
else
printf("%d\n",query(,x,y));
}
return ;
}
吉首大学2019年程序设计竞赛(重现赛)-K(线段树)的更多相关文章
- 吉首大学2019年程序设计竞赛(重现赛)D - 数列求和(嘤雄难度)
链接:https://ac.nowcoder.com/acm/contest/992/D $a_{i}=\dfrac {3a_{i-1}-a_{i-2}}{2}+i+1$ 移项再化一下 $a_{i}- ...
- 吉首大学2019年程序设计竞赛(重现赛)- A SARS病毒 (矩阵,欧拉降幂)
题目链接:https://ac.nowcoder.com/acm/contest/992/A 题意:求出长度为n的字符串个数,字符串由A.C.G.T组成,其中A和C必须成对出现. 思路:我们规定: ...
- 吉首大学2019年程序设计竞赛(重现赛)-J(树形DP)
题目链接:https://ac.nowcoder.com/acm/contest/992/J 题意:题意很清晰,就是求任意两点距离的和,结果对1e9+7取模. 思路:裸的树形DP题,一条边的贡献值=这 ...
- 吉首大学2019年程序设计竞赛(重现赛)I 滑稽树上滑稽果 (莫队+逆元打表)
链接:https://ac.nowcoder.com/acm/contest/992/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K ...
- 吉首大学2019年程序设计竞赛(重现赛) J 滑稽树下你和我 (递归)
链接:https://ac.nowcoder.com/acm/contest/992/J来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K ...
- 吉首大学2019年程序设计竞赛(重现赛) B 干物妹小埋
链接:https://ac.nowcoder.com/acm/contest/992/B来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K ...
- 第十四届浙江财经大学程序设计竞赛重现赛--A-A Sad Story
链接:https://www.nowcoder.com/acm/contest/89/A 来源:牛客网 1.题目描述 The Great Wall story of Meng Jiangnv’s Bi ...
- 牛客网 湖南大学2018年第十四届程序设计竞赛重现赛 A game
链接:https://www.nowcoder.com/acm/contest/125/A来源:牛客网 Tony and Macle are good friends. One day they jo ...
- 长安大学第四届ACM-ICPC“迎新杯”程序设计竞赛-重现赛 G - 彩虹岛套娃
题目描述 俄罗斯套娃是俄罗斯特产的木制玩具,一般由多个一样图案的空心木娃娃一个套一个组成,最多可达十多个,通常为圆柱形,底部平坦可以直立.颜色有红色,蓝色,绿色,紫色等.最普通的图案是一个穿着俄罗斯民 ...
随机推荐
- removeAttr(name)
removeAttr(name) 概述 从每一个匹配的元素中删除一个属性 1.6以下版本在IE6使用JQuery的removeAttr方法删除disabled是无效的.解决的方法就是使用$(" ...
- RestFul是啥
1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...
- Confluence 6 分享一个文件
协同合作和编辑不仅仅是发生在页面中,很多时候你需要与你的项目小组针对文档,报告,图片,表格进行协同操作.不管是针对性的市场计划或者一个完整的项目计划,你可以在 Confluence 中让你的项目小组成 ...
- CodeForces–830A--二分,贪心
Office Keys time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...
- 深入使用Vue + TS
深入使用TS 支持 render jsx 写法 这里一共分两步 首先得先让 vue 支持 jsx 写法 再让 vue 中的 ts 支持 jsx 写法 让 vue 支持 jsx 按照官方做法,安装Bab ...
- Linux下Weblogic 11g R1安装和配置
自己留着好好看看! 文章摘自 :http://blog.163.com/ng_0125@126/blog/static/170162360201311773235995/ 1. 安装前 1 确定w ...
- [BZOJ2730]:[HNOI2012]矿场搭建(塔尖)
题目传送门 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个 ...
- Keras学习笔记一:修改数据读入方式为本地图片读入
第一种方法: Keras官方给的图片去噪示例要自动下载mnist数据集并处理,不能修改和加入自己的数据集. from keras.datasets import mnist (x_train, _), ...
- postgres的数据库备份和恢复
备份和恢复 一条命令就可以解决很简单: 这是备份的命令: pg_dump -h 127/0.0.1 -U postgres databasename > databasename.bak 指令解 ...
- (十一)C语言之选择结构