题目链接: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(线段树)的更多相关文章

  1. 吉首大学2019年程序设计竞赛(重现赛)D - 数列求和(嘤雄难度)

    链接:https://ac.nowcoder.com/acm/contest/992/D $a_{i}=\dfrac {3a_{i-1}-a_{i-2}}{2}+i+1$ 移项再化一下 $a_{i}- ...

  2. 吉首大学2019年程序设计竞赛(重现赛)- A SARS病毒 (矩阵,欧拉降幂)

    题目链接:https://ac.nowcoder.com/acm/contest/992/A 题意:求出长度为n的字符串个数,字符串由A.C.G.T组成,其中A和C必须成对出现. 思路:我们规定:   ...

  3. 吉首大学2019年程序设计竞赛(重现赛)-J(树形DP)

    题目链接:https://ac.nowcoder.com/acm/contest/992/J 题意:题意很清晰,就是求任意两点距离的和,结果对1e9+7取模. 思路:裸的树形DP题,一条边的贡献值=这 ...

  4. 吉首大学2019年程序设计竞赛(重现赛)I 滑稽树上滑稽果 (莫队+逆元打表)

    链接:https://ac.nowcoder.com/acm/contest/992/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K  ...

  5. 吉首大学2019年程序设计竞赛(重现赛) J 滑稽树下你和我 (递归)

    链接:https://ac.nowcoder.com/acm/contest/992/J来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K ...

  6. 吉首大学2019年程序设计竞赛(重现赛) B 干物妹小埋

    链接:https://ac.nowcoder.com/acm/contest/992/B来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K ...

  7. 第十四届浙江财经大学程序设计竞赛重现赛--A-A Sad Story

    链接:https://www.nowcoder.com/acm/contest/89/A 来源:牛客网 1.题目描述 The Great Wall story of Meng Jiangnv’s Bi ...

  8. 牛客网 湖南大学2018年第十四届程序设计竞赛重现赛 A game

    链接:https://www.nowcoder.com/acm/contest/125/A来源:牛客网 Tony and Macle are good friends. One day they jo ...

  9. 长安大学第四届ACM-ICPC“迎新杯”程序设计竞赛-重现赛 G - 彩虹岛套娃

    题目描述 俄罗斯套娃是俄罗斯特产的木制玩具,一般由多个一样图案的空心木娃娃一个套一个组成,最多可达十多个,通常为圆柱形,底部平坦可以直立.颜色有红色,蓝色,绿色,紫色等.最普通的图案是一个穿着俄罗斯民 ...

随机推荐

  1. MacBook pro管理员变成普通用户无法解锁问题

    最近使用Mac的时候,把管理员的名字修改了一下,WTF?没有管理员权限了?然后就没有解锁权限了,这可以说是Mac的一个致命bug呀!下载软件也不可以了.具体我的解决方式在这里记录一下,以供和我遇到同样 ...

  2. JavaScript 小技巧整理

    1.过滤唯一值 Set类型是在ES6中新增的,它类似于数组,但是成员的值都是唯一的,没有重复的值.结合扩展运算符(...)我们可以创建一个新的数组,达到过滤原数组重复值的功能. const array ...

  3. 【原创】时隔十年,再度审视Performance Testing,性能测试,Load Runner,和企业级性能测试解决方案

    软件测试入行是2006年,最先学习的测试工具囊括了QTP,Test Director,Load Runner,Rational Robot,Rational Performance: 那时的操作系统是 ...

  4. 日照学习提高班day4测试

    A 思路: 一看到这个题,他不仅要求输出字典序最小的串,还要满足两两不重复,所以我们可以先输出ababab...什么的,最后缀上要求的k-2种字母 坑点: 当然这样想是不完全的!该题是拥有许多特殊情况 ...

  5. Liblinear Visual studio 2013 Error C3057

    使用LibLinear时编译时出现Error C3057的错误: OpenMP报错,查询MSDN: #pragma omp threadprivate(var)//var在编译之前必须是确定值 所以修 ...

  6. Vue_(组件)实例生命周期钩子

    Vue生命周期中文文档 传送门 Vue生命周期:Vue实例从创建到销毁的过程,称为Vue的生命周期: Vue生命周期钩子:又称为Vue生命周期钩子方法/函数,是Vue为开发者提供的方法,我们可以通过这 ...

  7. 2016 Multi-University Training Contest 4 部分题解

    1001,官方题解是直接dp,首先dp[i]表示到i位置的种类数,它首先应该等于dp[i-1],(假设m是B串的长度)同时,如果(i-m+1)这个位置开始到i这个位置的这一串是和B串相同的,那么dp[ ...

  8. scrapy_redis的使用

    配置Scrapy-Redis 配置Scrapy-Redis非常简单,只需要修改一下settings.py配置文件即可. 1. 核心配置 首先最主要的是,需要将调度器的类和去重的类替换为Scrapy-R ...

  9. 【学习】eclipse自动提示+自动补全

    解决代码的自动提示问题: 1.打开 Eclipse -> Window -> Perferences 2.找到Java 下的 Editor 下的 Content Assist , 右边出现 ...

  10. Nginx之监控进程和工作进程

    1. 函数调用分析 在开启 master 的情况下,多进程模型的下的入口函数为 ngx_master_process_cycle,如下: int mian() { ... if (ngx_proces ...