HDU 3397 Sequence operation 多标记线段树
/*
一开始维护了两个标记 开了两个数组
想的是 可能当前两种操作都要做
但是太复杂了 不好处理
其实 当前要做的标记可以只有一个 我们在Insert的时候 要打的标记是2即翻转区间: 1.如果原来是区间赋值1 先赋值1在翻转 问题不大 标记变 1-1=0
2.如果原来是区间赋值0 同上 问题不大 标记 1-0=1
3.如果原始是区间翻转 抵消1-2=-1
4.如果原来是-1 无标记 就打上 1-(-1)=2 这个时候要先把区间的01信息互换 要打的标记是01即区间赋值
就无视之前的翻转操作 直接打上标记更新k 然后Up的时候(标记下方)就只有一个标记
1.如果是2 就下放 改了左右儿子 然后同上进行标记改变
2.如果是01
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#define lc k*2
#define rc k*2+1
#define len (r-l+1)
#define mid (l+r)/2
#define maxn 400010
using namespace std;
int T,I,n,m,s1[maxn],s0[maxn],l1[maxn],l0[maxn],r1[maxn],r0[maxn],mx1[maxn],mx0[maxn],a[maxn];
void Swap(int k,int l,int r){
a[k]=-a[k];swap(s1[k],s0[k]);swap(l1[k],l0[k]);
swap(r1[k],r0[k]);swap(mx1[k],mx0[k]);
}
void Up(int k,int l,int r){
if(a[k]==){
a[k]=-;Swap(lc,l,mid);Swap(rc,mid+,r);return;
}
a[lc]=a[rc]=a[k];
s1[lc]=(mid-l+)*a[k];s0[lc]=(mid-l+)*(a[k]^);
s1[rc]=(r-mid)*a[k];s0[rc]=(r-mid)*(a[k]^);
l1[lc]=(mid-l+)*a[k];l0[lc]=(mid-l+)*(a[k]^);
l1[rc]=(r-mid)*a[k];l0[rc]=(r-mid)*(a[k]^);
r1[lc]=(mid-l+)*a[k];r0[lc]=(mid-l+)*(a[k]^);
r1[rc]=(r-mid)*a[k];r0[rc]=(r-mid)*(a[k]^);
mx1[lc]=(mid-l+)*a[k];mx0[lc]=(mid-l+)*(a[k]^);
mx1[rc]=(r-mid)*a[k];mx0[rc]=(r-mid)*(a[k]^);
a[k]=-;
}
void Insert(int k,int l,int r,int x,int y,int z){
if(x<=l&&y>=r){
if(z==)Swap(k,l,r);
else {
a[k]=z;s1[k]=len*z;s0[k]=len*(z^);mx1[k]=len*z;mx0[k]=len*(z^);
l1[k]=len*z;l0[k]=len*(z^);r1[k]=len*z;r0[k]=len*(z^);
}
return;
}
if(a[k]!=-)Up(k,l,r);
if(x<=mid)Insert(lc,l,mid,x,y,z);
if(y>mid)Insert(rc,mid+,r,x,y,z);
s1[k]=s1[lc]+s1[rc];s0[k]=s0[lc]+s0[rc];
l1[k]=l1[lc]+(l1[lc]==mid-l+)*l1[rc];
r1[k]=r1[rc]+(r1[rc]==r-mid)*r1[lc];
l0[k]=l0[lc]+(l0[lc]==mid-l+)*l0[rc];
r0[k]=r0[rc]+(r0[rc]==r-mid)*r0[lc];
mx1[k]=max(mx1[lc],max(mx1[rc],r1[lc]+l1[rc]));
mx0[k]=max(mx0[lc],max(mx0[rc],r0[lc]+l0[rc]));
}
int Query1(int k,int l,int r,int x,int y){
if(x<=l&&y>=r)return s1[k];
int res=;
if(a[k]!=-)Up(k,l,r);
if(x<=mid)res+=Query1(lc,l,mid,x,y);
if(y>mid)res+=Query1(rc,mid+,r,x,y);
return res;
}
int Query2(int k,int l,int r,int x,int y){
if(x<=l&&y>=r)return mx1[k];
if(a[k]!=-)Up(k,l,r);
int res=;
if(x<=mid)res=max(res,Query2(lc,l,mid,x,y));
if(y>mid)res=max(res,Query2(rc,mid+,r,x,y));
if(x<=mid&&y>mid)res=max(res,min(mid-x+,r1[lc])+min(y-mid,l1[rc]));
return res;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);int x,y,z;
for(int i=;i<=n*;i++)a[i]=-;
for(int i=;i<=n;i++){
scanf("%d",&x);Insert(,,n,i,i,x);
}
for(I=;I<=m;I++){
scanf("%d%d%d",&z,&x,&y);x++;y++;
if(z==||z==||z==)Insert(,,n,x,y,z);
if(z==)printf("%d\n",Query1(,,n,x,y));
if(z==)printf("%d\n",Query2(,,n,x,y));
}
}
return ;
}
HDU 3397 Sequence operation 多标记线段树的更多相关文章
- HDU 3397 Sequence operation(线段树)
HDU 3397 Sequence operation 题目链接 题意:给定一个01序列,有5种操作 0 a b [a.b]区间置为0 1 a b [a,b]区间置为1 2 a b [a,b]区间0变 ...
- hdu 3397 Sequence operation (线段树 区间合并 多重标记)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意: 给你一串01串,有5种操作 0. 区间全部变为0 1.区间全部变为1 2.区间异或 3.询问 ...
- hdu 3397 Sequence operation(线段树:区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给你一个长度为n的0,1序列,支持下列五种操作, 操作0(0 a b):将a到b这个区间的 ...
- hdu 3397 Sequence operation(很有意思的线段树题)
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 【线段树】HDU 3397 Sequence operation 区间合并
操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters i ...
- (简单) HDU 3397 Sequence operation,线段树+区间合并。
Problem Description lxhgww got a sequence contains n characters which are all '0's or '1's. We have ...
- hdu 3397 Sequence operation 线段树
题目链接 给出n个数, 每个数是0或1, 给5种操作, 区间变为1, 区间变为0, 区间0,1翻转, 询问区间内1的个数, 询问区间内最长连续1的个数. 需要将数组开成二维的, 然后区间0, 1翻转只 ...
- HDU 3397"Sequence operation"(线段树区间和并)
传送门 •题意 给你一个仅包含 0 和 1 的序列: 在这个序列上有如下操作: (1)0 a b : 将 [a,b] 区间的数置 0: (2)1 a b : 将 [a,b] 区间的数置 1: (3)2 ...
- hdu 3397 Sequence operation 线段树 区间更新 区间合并
题意: 5种操作,所有数字都为0或1 0 a b:将[a,b]置0 1 a b:将[a,b]置1 2 a b:[a,b]中的0和1互换 3 a b:查询[a,b]中的1的数量 4 a b:查询[a,b ...
随机推荐
- dropdownlist显示树形结构
/// <summary> /// 递归 /// </summary> /// <param name="deplist"></param ...
- Android sensor 系统框架 (一)
这几天深入学习了Android sensor框架,以此博客记录和分享分析过程,其中难免会有错误的地方,欢迎指出! 这里主要分析KERNEL->HAL->JNI这3层的流程.主要从以下几方面 ...
- [Windows Server 2008] 手工创建安全网站
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:手工创建安全站 ...
- 仿iphone动态萤火虫锁屏应用安卓源码
该源码是仿iphone动态萤火虫锁屏应用源码,源码SkyLock,这也是最近弄了一款锁屏,苦于市场百般阻拦与锁屏应用数量实在太多,于是将它拿出来开源:废话不多说,希望大家能够希望,更多说明请看下面的吧 ...
- Concurrency and Application Design
Concurrency and Application Design In the early days of computing, the maximum amount of work per un ...
- C# null
var t0est = Convert.ToString(""+null);//结果"" var t1est = ("" + null).T ...
- PHP 之websocket实现聊天室功能
一.功能界面 具体的详细代码:https://github.com/yangsphp/websocket-master/tree/master 二.具体代码实现 1.前端代码如下 <!DOCTY ...
- scss基础
1.变量$ 全局 局部 .div{ $color:yellow; } 2.类似函数@mixin border-radius($radius) { }引用:@include border-radius( ...
- CPU 指令集(Instruction Set Architecture, ISA)
本文摘自网络 概念 指令集是存储在CPU内部,对CPU运算进行指导和优化的硬程序,用来引导CPU进行加减运算和控制计算机操作系统的一系列指令集合.拥有这些指令集,CPU就可以更高效地运行.系统所下达的 ...
- Linux - VMware和Centos安装
目录 Linux - VMware和Centos安装 选择性 下载centos系统ISO镜像 安装虚拟机VMware虚拟机 1. 准备vmware软件 2. 解压软件包, 当前选择vm12 3. vm ...