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. 冲刺NO.6

    Alpha冲刺第六天 站立式会议 项目进展 项目中学生基本信息管理,与系统管理员模块基本完成,团队开始编写学生信用信息模块内容与奖惩事务管理内容,准备开始对已完成模块进行测试. 问题困难 团队成员对前 ...

  2. intellij idea 找不到或无法加载主类

    解决intellij idea 找不到或无法加载主类,请看以下图文介绍 然后idea会重启,等idea启动后 右侧的maven clean 一下,然后再compile就解决了

  3. linux作为服务器,利用top命令查看服务进程的耗用情况

    top命令查看进程服务如下: 其中shift+m可以按照内存的消耗进行排序,shift+p是按照cpu的消耗进程,排序,其中对cpu的消耗是一定时间,谁占用的时间越长消耗越大, 还有按空格键,会刷新一 ...

  4. Thinkphp框架部署步骤

    Thinkphp框架部署步骤 thinkphp框架部署起来简单,但是由于步骤较多也容易遗忘: 这是安装了集成环境后的一个www根目录结构: 然后需要在这个目录下面创建一个文件夹做项目:thinkphp ...

  5. 剑指offer-反转单词顺序列

    题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,"st ...

  6. api-gateway实践(09)支持rest服务注册

    一.GET-GET 1.前端定义 2.后端定义 2.1.基础定义 2.2.path参数.head参数.query参数 2.3.常量参数 2.4.系统参数 2.5.结果定义 二.POST-POST 1. ...

  7. 新概念英语(1-71)He's awful!

    He's awful!How did Pauline answer the telephone at the nine o'clock?A:What's Ron Marston like, Pauli ...

  8. Python基础学习篇章四

    一. Python数据类型之字典 1. 键的排序:for循环 由于字典不是序列,因此没有可靠的从左至右的顺序.这就导致当建立一个字典,将它打印出来,它的键也许会以与我们输入时的不同的顺序出现.有时候我 ...

  9. Python基础数据类型之字典

      基础数据类型之字典 ps:数据类型划分:可变数据类型和不可变数据类型. 不可变数据类型:元组(tupe).布尔值(bool).整数型(int).字符串(str).不可变数据类型也称为可哈希. 可变 ...

  10. 测试驱动开发实践4————testSave之新增文档分类

    [内容指引] 1.确定"新增文档分类"的流程及所需的参数 2.根据业务规则设计测试用例 3.为测试用例赋值并驱动开发 一.确定"新增文档分类"的流程及所需的参数 ...