HDU 3397 Sequence operation

题目链接

题意:给定一个01序列,有5种操作

0 a b [a.b]区间置为0

1 a b [a,b]区间置为1

2 a b [a,b]区间0变成1,1变成0

3 a b 查询[a,b]区间1的个数

4 a b 查询[a,b]区间连续1最长的长度

思路:线段树线段合并。须要两个延迟标记一个置为01,一个翻转,然后因为4操作,须要记录左边最长0、1。右边最长0、1,区间最长0、1,然后区间合并去搞就可以

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; #define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)
const int N = 100005; int t, n, m; struct Node {
int l, r, sum[3][2], num;
int setv, flip;
Node() {
setv = -1;
flip = 0;
}
int size() {return r - l + 1;}
void gao1(int v) {
setv = v;
num = v * (r - l + 1);
for (int i = 0; i < 3; i++) {
sum[i][v] = r - l + 1;
sum[i][!v] = 0;
}
flip = 0;
}
void gao2() {
flip ^= 1;
for (int i = 0; i < 3; i++)
swap(sum[i][0], sum[i][1]);
num = r - l + 1 - num;
}
} node[N * 4]; Node merge(Node lson, Node rson) {
Node x;
x.l = lson.l; x.r = rson.r;
for (int i = 0; i < 2; i++) {
x.sum[0][i] = lson.sum[0][i];
x.sum[1][i] = rson.sum[1][i];
x.sum[2][i] = max(lson.sum[2][i], rson.sum[2][i]);
if (lson.sum[0][i] == lson.size())
x.sum[0][i] += rson.sum[0][i];
if (rson.sum[1][i] == rson.size())
x.sum[1][i] += lson.sum[1][i];
x.sum[2][i] = max(x.sum[2][i], lson.sum[1][i] + rson.sum[0][i]);
}
x.num = lson.num + rson.num;
return x;
} void pushup(int x) {
node[x] = merge(node[lson(x)], node[rson(x)]);
} void pushdown(int x) {
if (node[x].setv != -1) {
node[lson(x)].gao1(node[x].setv);
node[rson(x)].gao1(node[x].setv);
node[x].setv = -1;
}
if (node[x].flip) {
node[lson(x)].gao2();
node[rson(x)].gao2();
node[x].flip = 0;
}
} void build(int l, int r, int x = 0) {
node[x].l = l; node[x].r = r;
node[x].setv = -1; node[x].flip = 0;
if (l == r) {
int tmp;
scanf("%d", &tmp);
for (int i = 0; i < 3; i++) {
node[x].sum[i][tmp] = 1;
node[x].sum[i][!tmp] = 0;
}
node[x].num = tmp;
return;
}
int mid = (l + r) / 2;
build(l, mid, lson(x));
build(mid + 1, r, rson(x));
pushup(x);
} void add(int l, int r, int v, int x = 0) {
if (node[x].l >= l && node[x].r <= r) {
if (v == 2) node[x].gao2();
else node[x].gao1(v);
return;
}
int mid = (node[x].l + node[x].r) / 2;
pushdown(x);
if (l <= mid) add(l, r, v, lson(x));
if (r > mid) add(l, r, v, rson(x));
pushup(x);
} Node query(int l, int r, int x = 0) {
if (node[x].l >= l && node[x].r <= r)
return node[x];
int mid = (node[x].l + node[x].r) / 2;
pushdown(x);
Node ans;
if (l <= mid && r > mid) ans = merge(query(l, r, lson(x)), query(l, r, rson(x)));
else if (l <= mid) ans = query(l, r, lson(x));
else if (r > mid) ans = query(l, r, rson(x));
pushup(x);
return ans;
} int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
build(0, n - 1);
int op, a, b;
while (m--) {
scanf("%d%d%d", &op, &a, &b);
if (op <= 2) add(a, b, op);
else if (op == 3) printf("%d\n", query(a, b).num);
else if (op == 4) printf("%d\n", query(a, b).sum[2][1]);
}
}
return 0;
}

HDU 3397 Sequence operation(线段树)的更多相关文章

  1. hdu 3397 Sequence operation (线段树 区间合并 多重标记)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意: 给你一串01串,有5种操作 0. 区间全部变为0 1.区间全部变为1 2.区间异或 3.询问 ...

  2. hdu 3397 Sequence operation 线段树

    题目链接 给出n个数, 每个数是0或1, 给5种操作, 区间变为1, 区间变为0, 区间0,1翻转, 询问区间内1的个数, 询问区间内最长连续1的个数. 需要将数组开成二维的, 然后区间0, 1翻转只 ...

  3. 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 ...

  4. hdu 3397 Sequence operation(线段树:区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给你一个长度为n的0,1序列,支持下列五种操作, 操作0(0 a b):将a到b这个区间的 ...

  5. hdu 3397 Sequence operation(很有意思的线段树题)

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

  6. 【线段树】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 ...

  7. hdu-3397 Sequence operation 线段树多种标记

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3397 题目大意: 0 a b表示a-b区间置为0 1 a b表示a-b区间置为1 2 a b表示a- ...

  8. Sequence operation(线段树区间多种操作)

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

  9. hdu3397 Sequence operation 线段树

    hdu3397 Sequence operation #include <bits/stdc++.h> using namespace std; ; struct node { /// l ...

随机推荐

  1. JQ 一些基本方法

    1.判断复选框是否有选中,bischecked 返回 ture 或 false var bischecked = $('[name=uid]').is(':checked'); 2.查看当前元素是父元 ...

  2. java 简单的数据增删该查

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...

  3. javascript 学习随笔1

    html部分 <body onload="message()"><!--主题部分加载就调用-->document.getElementById(" ...

  4. C++多态原理

    C++的多态性是通过动态绑定实现的 非虚函数是在编译时绑定的; 通过对象进行的函数(虚函数,非虚函数)也是编译时绑定的; C++编译器在编译的时候,要确定每个对象调用的函数(要求此函数是非虚函数)的地 ...

  5. QSerialPort

    (草稿) qt5提供QSerialPort类,封装了串口的api, 可以用这个类写串口通信程序.

  6. source insight 中文注释为乱码解决

    1. source insight 中文注释为乱码解决 http://blog.csdn.net/bingfeng1210/article/details/7527059 2. Source Insi ...

  7. 面向对象(类,实例变量,方法定义,方法重载,构造方法,this,string类)

    面向对象 类是由属性和方法组成 类是所有创建对象的模板 实例变量有默认值 实例变量至少在本类范围中有效 实例变量与局部变量冲突时,局部变量优先 类中方法定义类似于函数定义 修饰符 返回值类型 方法名( ...

  8. jsp_javabean

    什么是javabean? 遵循一定的设计原则的任何java类都可以是javabean组件 1.可序列化 implements serializable 2.无参数的构造方法 3.私有属性 通过公有方法 ...

  9. [转]php连接postgresql

    首先推荐一下postgres数据库,免费,强大,甚至某些方面比商业数据库还要好,大家可以试试. 安装: 附安装图解(网上找的):http://blog.sina.com.cn/s/blog_5edb7 ...

  10. android页面切换效果

    两种方式: 在activity的自定义主题中定义切换方式: overridePendingTransition()方法 自定义主题: 在项目的res/values/styles.xml中添加样式 &l ...