Sequence operation

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8308    Accepted Submission(s): 2507

Problem Description
lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
 
Input
T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
 
Output
For each output operation , output the result.
 
Sample Input
1
10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9
 
Sample Output
5
2
6
5
 
Author
lxhgww&&shǎ崽
及其恶心的一道题目,要维护许多变量= =
由于mx1函数写错找bug找了半天,最后发现自己的思路错了诶,可算A了。
中间维护的变量: 1的个数,0的个数,以第一个开始的最长连续0,以第一个开始的最长连续1,以最后一个开始的最长连续0,以最后一个开始的最长连续1,
区间最长连续1,区间最长连续0,可能有一些变量是互补的我写的有点多余不过感觉很方便把看起来,另外注意当操作为0/1时可以覆盖之前所有的标记。
我用0,1,2表示三种标记全0全1和翻转。len储存区间信息 一维表示'0'/'1'   二维表示 head,tail,max_continue_1  三维表示区间对应的结点值。
 #include<bits/stdc++.h>
using namespace std;
#define MAXN ((100000<<2)+15)
int g[][]={,,,,,,,,-};
struct SegmentTree
{
#define M ((L+R)>>1)
#define lc (id<<1)
#define rc (id<<1|1)
int num[MAXN][],X;
int len[][][MAXN];
short int laz[MAXN];
void show(int L,int R,int id)
{
if(L==R) {cout<<num[id][]<<" ";return;}
push_down(L,R,id);
show(L,M,lc);
show(M+,R,rc);
push_up(L,R,id);
}
void init()
{
memset(num,,sizeof(num));
memset(laz,-,sizeof(laz));
memset(len,,sizeof(len));
}
void push_up(int L,int R,int id)
{
num[id][]=num[lc][]+num[rc][];
num[id][]=num[lc][]+num[rc][];
for(int i=;i<=;++i){
len[i][][id]=len[i][][lc];
len[i][][id]=len[i][][rc];
len[i][][id]=max(max(len[i][][lc],len[i][][rc]),len[i][][lc]+len[i][][rc]);
if(!num[lc][i^]) len[i][][id]=max(len[i][][id],len[i][][lc]+len[i][][rc]);
if(!num[rc][i^]) len[i][][id]=max(len[i][][id],len[i][][rc]+len[i][][lc]);
}
}
void push_down(int L,int R,int id)
{
if(laz[id]==-) return;
laz[lc]=laz[lc]==-?laz[id]:g[laz[id]][laz[lc]];
laz[rc]=laz[rc]==-?laz[id]:g[laz[id]][laz[rc]];
if(laz[id]<){
num[lc][laz[id]^]=num[rc][laz[id]^]=;
num[lc][laz[id]]=M-L+;
num[rc][laz[id]]=R-M;
len[laz[id]^][][lc]=len[laz[id]^][][lc]=len[laz[id]^][][lc]=;
len[laz[id]^][][rc]=len[laz[id]^][][rc]=len[laz[id]^][][rc]=;
len[laz[id]][][lc]=len[laz[id]][][lc]=len[laz[id]][][lc]=M-L+;
len[laz[id]][][rc]=len[laz[id]][][rc]=len[laz[id]][][rc]=R-M;
}
else {
swap(num[lc][],num[lc][]);
swap(num[rc][],num[rc][]);
swap(len[][][lc],len[][][lc]); swap(len[][][lc],len[][][lc]); swap(len[][][lc],len[][][lc]);
swap(len[][][rc],len[][][rc]); swap(len[][][rc],len[][][rc]); swap(len[][][rc],len[][][rc]);
}
laz[id]=-;
}
void build(int L,int R,int id)
{
if(L==R)
{
scanf("%d",&X);num[id][X]++;
len[X][][id]=len[X][][id]=len[X][][id]=;
return;
}
build(L,M,lc);
build(M+,R,rc);
push_up(L,R,id);
}
void change(int L,int R,int id,int l,int r,int x)
{
if(L>=l&&R<=r){
num[id][x^]=;
num[id][x]=R-L+;
len[x][][id]=len[x][][id]=len[x][][id]=R-L+;
len[x^][][id]=len[x^][][id]=len[x^][][id]=;
laz[id]=laz[id]==-?x:g[x][laz[id]];
return;
}
push_down(L,R,id);
if(l<=M) change(L,M,lc,l,r,x);
if(r>M) change(M+,R,rc,l,r,x);
push_up(L,R,id);
}
void swp(int L,int R,int id,int l,int r)
{
if(L>=l&&R<=r){
swap(num[id][],num[id][]);
laz[id]=laz[id]==-?:g[][laz[id]];
swap(len[][][id],len[][][id]);
swap(len[][][id],len[][][id]);
swap(len[][][id],len[][][id]);
return;
}
push_down(L,R,id);
if(l<=M) swp(L,M,lc,l,r);
if(r>M) swp(M+,R,rc,l,r);
push_up(L,R,id);
}
int num1(int L,int R,int id,int l,int r)
{
if(L>=l&&R<=r) return num[id][];
push_down(L,R,id);
int s=;
if(l<=M) s+=num1(L,M,lc,l,r);
if(r>M) s+=num1(M+,R,rc,l,r);
push_up(L,R,id);
return s;
}
int mx1(int L,int R,int id,int l,int r)
{
if(L>=l&&R<=r) return len[][][id];
push_down(L,R,id);
int s=;
if(r<=M) s=max(s, mx1(L,M,lc,l,r));
else if(l>M) s=max(s,mx1(M+,R,rc,l,r));
else {
int lm=len[][][lc],rm=len[][][rc];
if(lm>M-l+) lm=M-l+;
if(rm>r-M) rm=r-M;
s=max(s,max(max(mx1(L,M,lc,l,r),mx1(M+,R,rc,l,r)),lm+rm));
}
push_up(L,R,id);
return s;
}
}seg; int main()
{
int t,n,m,i,j,k,opt,a,b;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
seg.init();
seg.build(,n,);
while(m--){
scanf("%d%d%d",&opt,&a,&b);a++;b++;
if(opt==) seg.change(,n,,a,b,);
else if(opt==) seg.change(,n,,a,b,);
else if(opt==) seg.swp(,n,,a,b);
else if(opt==) printf("%d\n",seg.num1(,n,,a,b));
else printf("%d\n",seg.mx1(,n,,a,b));
}
}
return ;
}

HDU 3397 线段树区间修改的更多相关文章

  1. E - Just a Hook HDU - 1698 线段树区间修改区间和模版题

    题意  给出一段初始化全为1的区间  后面可以一段一段更改成 1 或 2 或3 问最后整段区间的和是多少 思路:标准线段树区间和模版题 #include<cstdio> #include& ...

  2. HDU - 1698 线段树区间修改,区间查询

    这就是很简单的基本的线段树的基本操作,区间修改,区间查询,对区间内部信息打上laze标记,然后维护即可. 我自己做的时候太傻逼了...把区间修改写错了,对给定区间进行修改的时候,mid取的是节点的左右 ...

  3. Hdu 1698(线段树 区间修改 区间查询)

    In the game of DotA, Pudge's meat hook is actually the most horrible thing for most of the heroes. T ...

  4. hdu 1698 线段树 区间修改

    #include <cstdio> #include <cstdlib> #include <cmath> #include <map> #includ ...

  5. 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)

    Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...

  6. hdu 3397 线段树双标记

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)

    题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...

  8. poj 2528 线段树区间修改+离散化

    Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...

  9. POJ 3667 & HDU 3308 & HDU 3397 线段树的区间合并

    看到讲课安排上 线段树有一节课"区间合并" 我是迷茫的 因为并没有见过 然后了解了一下题目 发现以前写过 还是很麻烦的树链剖分 大概是 解决带修改的区间查询"连续问题&q ...

随机推荐

  1. KDDCUP CTR预测比赛总结

    赛题与数据介绍 给定查询和用户信息后预测广告点击率 搜索广告是近年来互联网的主流营收来源之一.在搜索广告背后,一个关键技术就是点击率预测-----pCTR(predict the click-thro ...

  2. 百度NLP一面

    C++ :     1.拷贝构造函数和重载=符分别在什么情况下被调用,实现有什么区别 2.虚函数的目的,虚函数和模板类的区别,如何找到虚函数 常规算法: 1. 如何输出一个集合的所有真子集,递归和非递 ...

  3. golang在线手册汇总

    1. golang官网 https://golang.org/ 2. golang中国 http://www.golangtc.com/ http://godoc.golangtc.com/pkg/ ...

  4. python全栈开发从入门到放弃之常用模块和正则

    什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写的代码(.p ...

  5. undefined reference to `__sync_bool_compare_and_swap_4

    然后开始glibc的编译工作. 你必须设定march这个参数才行,要不然会出现“undefined reference to `__sync_bool_compare_and_swap_4′.”这个错 ...

  6. property函数的使用

    描述 property函数的作用是在新式类中返回属性值 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改 s=Student() s.score= ...

  7. http超文本传输协议,get与post区别

    一:什么是http? http:超文本传输协议(HTTP,HyperText Transfer Protocol),是一个客户端和服务器端传输的标准,是应用层通信协议.客户端是中端用户,服务器端是网站 ...

  8. Word 中将正文中的参考文件标号链接到参考文献具体条目

    一.概论 在论文撰写过程中,不可避免地引用到参考文献.通常,论文格式要求我们在引用的正文后,使用中括号将参考文献章节中对应的出处条目序号引起来,例如: 有时,我们要建立起这两者之间的链接关系. 二.设 ...

  9. LinQ高级查询、组合查询、IQueryable集合类型

    LinQ高级查询: 1.模糊查询(包含) Repeater1.DataSource = con.car.Where(r =>r.name.Contains(s)).ToList(); 2.开头 ...

  10. zookeeper和淘宝dubbo的关系

    Dubbo建议使用Zookeeper作为服务的注册中心. 1.   Zookeeper的作用:         zookeeper用来注册服务和进行负载均衡,哪一个服务由哪一个机器来提供必需让调用者知 ...