链接:https://ac.nowcoder.com/acm/contest/925/K
来源:牛客网

题目描述

公元2019年6月22日,白山茶王国与红玫瑰王国展开大战,在世外仙境——天空花园处,双方军团一字排开,在维持一字长蛇阵的队形下双方战士陷入混战。
然而,为了操控整个战局,白山茶公主与红玫瑰女巫都会一种AOE魔法,使得受到魔法波及的战士"叛变"(白山茶战士变为红玫瑰战士,红玫瑰战士变为白山茶战士)。
可见,这场战争永远没有绝对的优劣势,局势瞬息万变。现在,白山茶公主邀请你协助她了解各个区块的战况。

输入描述:

第一行一个整数n( 0 < n <= 105),表示白山茶战士和红玫瑰战士的数量和。
第二行n个只包含0、1的整数,为一字长蛇阵中的战士类别(1为白山茶战士,0为红玫瑰战士,下标从1开始)。
第三行一个整数m(0 < m <= 100001),表示施放魔法和询问战况的操作次数。
随后m行,每行三个整数op,x,y: (op∈∈ {0,1};1 <= x <= y <= n )
    对于op=1,表示对下标属于闭区间[x,y]的战士施放魔法,使她们"叛变";
    对于op=0,表示询问下标属于闭区间[x,y]的连续最多的白山茶战士的数目。

输出描述:

对于每一次op=0的操作,输出区间内连续最多的白山茶战士数目。
示例1

输入

复制

4
1 0 1 0
5
0 1 4
1 2 3
0 1 4
1 3 3
0 4 4

输出

复制

1
2
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 白山茶与红玫瑰 (线段树区间操作)的更多相关文章

  1. 校赛F 比比谁更快(线段树)

    http://acm.cug.edu.cn/JudgeOnline/problem.php?cid=1153&pid=5 题意:给你一个字符串,各两个操作: ch=0,[l,r]降序 ch=1 ...

  2. hpu校赛--雪人的高度(离散化线段树)

    1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec  内存限制: 128 MB 提交: 81  解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...

  3. 计蒜客 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 ...

  4. 《白书》上线段树RMQ的实现

    白书上的线段树RMQ实现,自己重写了一遍: #include <bits/stdc++.h> using namespace std; const int MAXN=1<<17 ...

  5. HDU5039--Hilarity DFS序+线段树区间更新 14年北京网络赛

    题意:n个点的树,每个条边权值为0或者1, q次操作 Q 路径边权抑或和为1的点对数, (u, v)(v, u)算2个. M i修改第i条边的权值 如果是0则变成1, 否则变成0 作法: 我们可以求出 ...

  6. HDU5107---K-short Problem (线段树区间 合并、第k大)

    题意:二维平面上 N 个高度为 Hi 建筑物,M次询问,每次询问输出 位于坐标(x ,y)左下角(也就是xi <= x && yi <= y)的建筑物中的第k高的建筑物的高 ...

  7. BZOJ3110[Zjoi2013]K大数查询——权值线段树套线段树

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...

  8. BZOJ 3110 [ZJOI2013]K大数查询 (整体二分+线段树)

    和dynamic rankings这道题的思想一样 只不过是把树状数组换成线段树区间修改,求第$K$大的而不是第$K$小的 这道题还有负数,需要离散 #include <vector> # ...

  9. [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)

    [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...

随机推荐

  1. 查询qq登陆状态

    function qq_status(){ if (empty($qq))$qq = 287959133; $url = 'http://wpa.qq.com/pa?p=2:'.$qq.':52'; ...

  2. 自己封装 vue 组件 和 插件

    vue 组件 一.组件的创建,两种方法.(本质上是1.2两种,vue文件,只是创建了一个  组件选项对象,仅是一个js对象)1.定义组件:Vue.component('button-counter', ...

  3. 【Shiro】六、Apache Shiro Session管理

    1.Session的介绍 关于Session 会话:从启动一个Session到关闭这个Session作为一个会话,是对客户端和服务器端交互的一种封装,带有时效性 会话的产生: 一般从容器中产生 Web ...

  4. CentOS 7.0 lamp

    CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙. 1.关闭firewall: systemctl stop firewalld.service #停止fir ...

  5. Hive 时间操作函数(转)

    1.日期函数UNIX时间戳转日期函数: from_unixtime 语法:   from_unixtime(bigint unixtime[, string format]) 返回值: string ...

  6. 漫谈C语言结构体【转】

    相信大家对于结构体都不陌生.在此,分享出本人对C语言结构体的学习心得.如果你发现这个总结中有你以前所未掌握的,那本文也算是有点价值了.当然,水平有限,若发现不足之处恳请指出.代码文件test.c我放在 ...

  7. 服务安全-OAuth-OAuth2.0:百科

    ylbtech-服务安全-OAuth-OAuth2.0:百科 OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 2.0即完全废止了OAuth1.0. OAuth 2.0关注客户端开发 ...

  8. (12)C++ 继承

    1继承语法 class Base { public: void print() { cout << "Base" << endl; } }; class S ...

  9. 自己写一个 wsgi 服务器运行 Django 、Tornado 等框架应用

    https://blog.csdn.net/heybob/article/details/52288006

  10. 16. Django基础数据访问

    如果我们想使用Django对数据库进行访问,我们可以使用django自带的shell. 进入blog目录,打开cmd命令窗口,输入python manage.py shell,如下图所示: 插入数据 ...