Sequence operation

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

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
/*
hdu 3397 线段树双标记 给你5个操作:
0:将区间[a,b]之间的数全部置为0
1:将区间[a,b]之间的数全部置为1
2:将区间[a,b]之间的 1->0 0->1
3:求区间[a,b]之间1的个数
4:求区间[a,b]之间1的最长连续长度 先设定ls1,rs1,ms1,num1 ls0,rs0,ms0,num0分别记录1,0的情况
然后是rev和same标记,区间合并这些到是没什么问题,主要是在标记下放
最开始没有注意标记之间的互相影响的问题,假设[a,b]上即有rev又有same
我们应该怎么处理之.所以最开始WR了几次,然后想只记录same标记,当进行
rev操作时 要么更新到点,要么遇到same对标记进行修改,尝试了很久,一直
TLE 然后考虑same和rev之间的关系,
假设same在[a,b]上遇到一个rev,那么把该区间上原先有的rev删除.
如果rev在[a,b]上遇见一个same标记,那么只需要对same进行修改即可,否则
将0 1的数据进行交换 hhh-2016-04-01 21:52:19
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <functional>
using namespace std;
#define lson (i<<1)
#define rson ((i<<1)|1)
typedef long long ll;
const int maxn = 200050; struct node
{
int l,r;
int same,rev;
int ls1,rs1,ms1;
int ls0,rs0,ms0;
int num1,num0;
int mid()
{
return (l+r)>>1;
}
int len()
{
return (r-l+1);
}
} tree[maxn<<2]; void push_up(int i)
{
tree[i].ls0 = tree[lson].ls0,tree[i].ls1 = tree[lson].ls1;
tree[i].rs0 = tree[rson].rs0,tree[i].rs1 = tree[rson].rs1;
tree[i].num1 = tree[lson].num1 + tree[rson].num1;
tree[i].num0 = tree[lson].num0 + tree[rson].num0; if(tree[i].ls1 == tree[lson].len() )
tree[i].ls1 += tree[rson].ls1;
if(tree[i].ls0 == tree[lson].len() )
tree[i].ls0 += tree[rson].ls0;
if(tree[i].rs1 == tree[rson].len() )
tree[i].rs1 += tree[lson].rs1;
if(tree[i].rs0 == tree[rson].len() )
tree[i].rs0 += tree[lson].rs0;
tree[i].ms1 = max(tree[lson].ms1,tree[rson].ms1);
tree[i].ms0 = max(tree[lson].ms0,tree[rson].ms0);
tree[i].ms1 = max(tree[i].ms1,tree[lson].rs1+tree[rson].ls1);
tree[i].ms0 = max(tree[i].ms0,tree[lson].rs0+tree[rson].ls0);
}
void ini1(int i,int val)
{
tree[i].num1=tree[i].ls1 = tree[i].rs1 = tree[i].ms1 = val;
} void ini0(int i,int val)
{
tree[i].num0=tree[i].ls0 = tree[i].rs0 = tree[i].ms0 = val;
} void build(int i,int l,int r)
{
tree[i].l = l,tree[i].r = r;
ini1(i,0),ini0(i,0);
tree[i].same = -1;
tree[i].rev = 0;
if(l == r)
{
int x;
scanf("%d",&x);
if(x)
ini1(i,1);
else
ini0(i,1);
return ;
}
int mid = tree[i].mid();
build(lson,l,mid);
build(rson,mid+1,r);
push_up(i);
} void exchange(int i)
{
swap(tree[i].ls1,tree[i].ls0);
swap(tree[i].rs1,tree[i].rs0);
swap(tree[i].ms0,tree[i].ms1);
swap(tree[i].num0,tree[i].num1);
} void solve(int i)
{
tree[i].same ^= 1;
if(tree[i].same)
{
ini1(i,tree[i].len());
ini0(i,0);
}
else
{
ini1(i,0);
ini0(i,tree[i].len());
}
} void push_down(int i)
{
if(tree[i].same != -1)
{
tree[lson].rev = tree[rson].rev = 0;
tree[lson].same = tree[i].same;
tree[rson].same = tree[i].same;
if(tree[i].same)
{
ini1(lson,tree[lson].len()),ini0(lson,0);
ini1(rson,tree[rson].len()),ini0(rson,0);
}
else
{
ini1(lson,0),ini1(rson,0);
ini0(lson,tree[lson].len()),ini0(rson,tree[rson].len());
}
tree[i].same = -1;
}
if(tree[i].rev)
{
if(tree[lson].same != -1)
{
solve(lson);
}
else
{
tree[lson].rev ^= 1;
exchange(lson);
}
if(tree[rson].same != -1)
{
solve(rson);
}
else
{
tree[rson].rev ^= 1;
exchange(rson);
}
tree[i].rev = 0;
}
} void update_same(int i,int l,int r,int va)
{
if(tree[i].l >= l && tree[i].r <= r )
{
tree[i].rev = 0;
if(va)
{
ini1(i,tree[i].len()),ini0(i,0);
}
else
{
ini1(i,0),ini0(i,tree[i].len());
}
tree[i].same = va;
return;
}
push_down(i);
int mid = tree[i].mid();
if(l <= mid)
update_same(lson,l,r,va);
if(r > mid)
update_same(rson,l,r,va);
push_up(i);
} void update_rev(int i,int l,int r)
{
if(tree[i].l >= l && tree[i].r <= r)
{
if(tree[i].same != -1)
{
solve(i);
return ;
}
tree[i].rev ^= 1;
exchange(i);
return;
}
push_down(i);
int mid = tree[i].mid();
if(l <= mid)
update_rev(lson,l,r);
if(r > mid)
update_rev(rson,l,r);
push_up(i);
} int query1(int i,int l,int r)
{
if(tree[i].l >= l && tree[i].r <= r)
{
return tree[i].ms1;
}
int mid = tree[i].mid();
push_down(i);
if(r <= mid)
return query1(lson,l,r);
else if(l > mid)
return query1(rson,l,r);
else
{
int ans1 = query1(lson,l,mid);
int ans2 = query1(rson,mid+1,r);
return max(max(ans1,ans2),min(tree[lson].rs1,mid-l+1)+min(tree[rson].ls1,r-mid));
}
} int query2(int i,int l,int r)
{
if(l <= tree[i].l && tree[i].r <= r)
{
return tree[i].num1;
}
push_down(i);
int mid = tree[i].mid();
int num = 0;
if(l <= mid)
num += query2(lson,l,r);
if(r > mid)
num += query2(rson,l,r);
return num;
} int op;
int x,y;
int T,n,m;
int main()
{ scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
build(1,0,n-1); while(m--)
{
scanf("%d",&op);
scanf("%d%d",&x,&y);
if(op == 0)
update_same(1,x,y,0);
else if(op == 1)
update_same(1,x,y,1);
else if(op == 2)
update_rev(1,x,y);
else if(op == 3)
printf("%d\n",query2(1,x,y));
else
printf("%d\n",query1(1,x,y));
}
}
return 0;
}

  

hdu 3397 线段树双标记的更多相关文章

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

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

  2. hdu 3397 线段树

    题意: Change operations:0 a b change all characters into '0's in [a , b]1 a b change all characters in ...

  3. HDU 3397 线段树区间修改

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

  4. HDU 3397 线段树 双懒惰标记

    这个是去年遗留历史问题,之前思路混乱,搞了好多发都是WA,就没做了 自从上次做了大白书上那个双重懒惰标记的题目,做这个就思路很清晰了 跟上次大白上那个差不多,这个也是有一个sets标记,代表这个区间全 ...

  5. hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  6. hdu 3974 线段树 将树弄到区间上

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  8. hdu 4578 线段树(标记处理)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) ...

  9. hdu 4533 线段树(问题转化+)

    威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

随机推荐

  1. 201621123057 《Java程序设计》第7周学习总结

    1. 本周学习总结 1.1 思维导图:Java图形界面总结 1.2 可选:使用常规方法总结其他上课内容. 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 答: ...

  2. Python strip()方法

    描述 Python strip() 方法用于移除字符串头尾指定的字符(默认为空格). 语法 strip()方法语法: str.strip([chars]); 参数 chars -- 移除字符串头尾指定 ...

  3. ubuntu1604使用源码方式安装ruby2.5.0

    本文介绍ubutntu1604环境下源代码方式安装ruby 版本2.5.0 如果内存小于2G可以开启虚拟内存,下面的命令开启4G虚拟内存 sudo dd if=/dev/zero of=/swap b ...

  4. 16-TypeScript装饰器模式

    在客户端脚本中,有一个类通常有一个方法需要执行一些操作,当我们需要扩展新功能,增加一些操作代码时,通常需要修改类中方法的代码,这种方式违背了开闭的原则. 装饰器模式可以动态的给类增加一些额外的职责.基 ...

  5. 新概念英语(1-105)Full Of Mistakes

    Lesson 105 Full of mistakes 错误百出 Listen to the tape then answer this question. What was Sandra's pre ...

  6. T410升级笔记

      T410 win7 旗舰版 32 sp1 三星  DDR3 1066 mhz core i5 M 540 2.53GHZ 双核 日立 HTS725032A9A364 320G/7200转/分 sa ...

  7. python入门(6)输入和输出

    python入门(6)输入和输出 输出 >>> print 'hello, world' >>> print 'The quick brown fox', 'jum ...

  8. MYSQL之视图、触发器、存储过程、函数、事物、数据库锁和数据库备份

    一.视图 -- view 视图:是一个虚报表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据. 视图有如下特点: 1.视图的列可以来自不同的表,是表的抽象和逻辑意义上建立的新关系 ...

  9. 解决cors跨域的filter

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; im ...

  10. windows下nginx代理ftp服务器

    我所在的开发环境里,nginx和ftp在同一台服务器. ftp根目录: nginx的配置: 在nginx.conf中加入: server { listen ; server_name localhos ...