吉首大学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 - 彩虹岛套娃
题目描述 俄罗斯套娃是俄罗斯特产的木制玩具,一般由多个一样图案的空心木娃娃一个套一个组成,最多可达十多个,通常为圆柱形,底部平坦可以直立.颜色有红色,蓝色,绿色,紫色等.最普通的图案是一个穿着俄罗斯民 ...
随机推荐
- 【Python之路】特别篇--Python装饰器
前情提要 1. 作用域 在python中,函数会创建一个新的作用域.python开发者可能会说函数有自己的命名空间,差不多一个意思.这意味着在函数内部碰到一个变量的时候函数会优先在自己的命名空间里面去 ...
- fish-redux快速创建文件夹模板 FishReduxTemplate
推荐一款插件: 在插件plugins中搜 FishReduxTemplate
- codeforces613E
Puzzle Lover CodeForces - 613E Oleg Petrov loves crossword puzzles and every Thursday he buys his fa ...
- 使用Python操作Excel文档(一)
Python | 使用Python操作Excel文档(一) 0 前言 在阅读本文之前,请确保您已满足或可能满足以下条件: 请确保您具备基本的Python编程能力. 请确保您会使用Excel. 请确保您 ...
- 线程系列2--Java线程的互斥技术
java的多线程互斥主要通过synchronized关键字实现.一个线程就是一个执行线索,多个线程可理解为多个执行线索.进程有独立的内存空间,而进程中的线程则是共享数据对象资源.这样当多个执行线索在C ...
- python配置文件
python有两种配置文件,file.ini和file.json 一.ini文件如下: db_config.ini [baseconf] host=127.0.0.1 port=3306 user=r ...
- Java中的基本数据类型和引用类型
一.基本数据类型: byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围-32768 ...
- 类 kotlin(13)
Kotlin 中使用关键字 class 声明类class Invoice {} 类声明由类名.类头(指定其类型参数.主 构造函数等) 和由大括号包围的类体构成.类头和类体都是可选的:如果一个类没有类体 ...
- 百度地图js判断点是否在圆形区域内
/** * Created by LEGION on 2018/10/11. *//** * @fileoverview GeoUtils类提供若干几何算法,用来帮助用户判断点与矩形. * 圆形.多边 ...
- Android jni/ndk编程一:jni初级认识与实战体验
Android平台很多地方都可以看到jni的身影,比如之前接触到一个投屏的项目,主要的代码是c/c++写的,然后通过Jni供Java层调用;另外,就拿Android系统中的Service来说,很多的S ...