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. Xcode8免证书生产IPA打包文件

    免证书生产IPA打包文件   修改Xcode配置文件: 关闭Xcode.然后打开“其他-终端”,就是命令行工具 cd /Applications/Xcode.app/Contents/Develope ...

  2. linxu系统压缩解压命令

    使用cat命令进行文件的纵向合并 两种文件的纵向合并方法 归档文件和归档技术 归档的目的 什么是归档 tar命令的功能 tar命令的常用选项 使用tar命令创建.查看及抽取归档文件 使用tar命令创建 ...

  3. 264. Ugly Number II(丑数 剑指offer 34)

    Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime factors ...

  4. Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) E Underground Lab

    地址:http://codeforces.com/contest/782/problem/E 题目: E. Underground Lab time limit per test 1 second m ...

  5. LRU算法---缓存淘汰算法

    计算机中的缓存大小是有限的,如果对所有数据都缓存,肯定是不现实的,所以需要有一种淘汰机制,用于将一些暂时没有用的数据给淘汰掉,以换入新鲜的数据进来,这样可以提高缓存的命中率,减少磁盘访问的次数. LR ...

  6. “凯易迅Calix”实习上机——打折问题

    题目要求: 题目记得不太清楚,大概的意思是一个商店的打折方案如下:设一个客户买了n个商品,价格分别是p1,p2,...,pn (1)第一个商品不打折,即cost=p1; (2)第i个商品的折扣d=mi ...

  7. Java最佳实战

    1. 针对日志记录的优化:logback , 预编译形式记录日志,开发debug,生产info,访问日志和错误日志分开,异常日志输出到单独文件 2. 针对数据库连接的优化 :单例模式或数据库连接池 3 ...

  8. windows7上安装php7和apche2.4

    windows7在配置php7+apache2.4 1.下载并安装vc14http://www.microsoft.com/zh-cn/download/details.aspx?id=48145下载 ...

  9. dubbo-admin 监控中心 部署

    dubbo-admin部署 下载: GitHub:https://github.com/search?q=dubbo-admin 百度网盘: 链接:https://pan.baidu.com/s/1v ...

  10. [日志] spring boot + logback 日志输出配置

    一.输出日志到控制台 springboot有很多starter(参考starter)方便快速构建项目依赖组件,logback是springboot默认的日志组件,启动即可看到打印在控制台输出的info ...