题目链接

给出n个数, 每个数是0或1, 给5种操作, 区间变为1, 区间变为0, 区间0,1翻转, 询问区间内1的个数, 询问区间内最长连续1的个数。

需要将数组开成二维的, 然后区间0, 1翻转只需要交换一个数组的第二维就可以。

一个数组记录区间最长, 一个记录前缀, 一个记录后缀, 一个记录总数, 一个lazy标记, 一个xor标记。

如果遇到覆盖的情况, 那么这个区间如果原先有xor标记, 那么直接将xor清零。

这个题我写的代码可能不太适合人类观看............

 #include<bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, a, n) for(int i = a; i<n; i++)
#define ull unsigned long long
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = 1e5+;
int maxx[maxn<<][], pre_max[maxn<<][], suf_max[maxn<<][], XOR[maxn<<], lazy[maxn<<], sum[maxn<<][];
void pushUp(int rt, int sign, int m) {
maxx[rt][sign] = max(maxx[rt<<][sign], maxx[rt<<|][sign]);
pre_max[rt][sign] = pre_max[rt<<][sign];
suf_max[rt][sign] = suf_max[rt<<|][sign];
sum[rt][sign] = sum[rt<<][sign]+sum[rt<<|][sign];
if(pre_max[rt][sign] == (m-(m>>)))
pre_max[rt][sign] += pre_max[rt<<|][sign];
if(suf_max[rt][sign] == (m>>))
suf_max[rt][sign] += suf_max[rt<<][sign];
maxx[rt][sign] = max(maxx[rt][sign], suf_max[rt<<][sign]+pre_max[rt<<|][sign]);
}
void change(int rt) {
swap(sum[rt][], sum[rt][]);
swap(maxx[rt][], maxx[rt][]);
swap(pre_max[rt][], pre_max[rt][]);
swap(suf_max[rt][], suf_max[rt][]);
XOR[rt]^=;
}
void pushDown(int rt, int m) {
if(~lazy[rt]) {
XOR[rt<<] = XOR[rt<<|] = ;
int sign = lazy[rt];
maxx[rt<<][sign] = sum[rt<<][sign] = pre_max[rt<<][sign] = suf_max[rt<<][sign] = (m-(m>>));
maxx[rt<<|][sign] = sum[rt<<|][sign] = pre_max[rt<<|][sign] = suf_max[rt<<|][sign] = (m>>);
sign^=;
maxx[rt<<][sign] = sum[rt<<][sign] = pre_max[rt<<][sign] = suf_max[rt<<][sign] = ;
maxx[rt<<|][sign] = sum[rt<<|][sign] = pre_max[rt<<|][sign] = suf_max[rt<<|][sign] = ;
lazy[rt<<] = lazy[rt<<|] = lazy[rt];
lazy[rt] = -;
}
if(XOR[rt]) {
change(rt<<);
change(rt<<|);
XOR[rt] = ;
}
}
void build(int l, int r, int rt) {
XOR[rt] = , lazy[rt] = -;
if(l == r) {
int sign;
scanf("%d", &sign);
sum[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = maxx[rt][sign] = ;
sign^=;
sum[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = maxx[rt][sign] = ;
return ;
}
int m = l+r>>;
build(lson);
build(rson);
pushUp(rt, , r-l+);
pushUp(rt, , r-l+);
}
void update(int L, int R, int l, int r, int rt, int sign) {
if(L<=l&&R>=r) {
if(sign == ) {
change(rt);
} else {
lazy[rt] = sign;
sum[rt][sign] = maxx[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = (r-l+);
sign ^= ;
sum[rt][sign] = maxx[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = ;
XOR[rt] = ;
}
return ;
}
pushDown(rt, r-l+);
int m = l+r>>;
if(L<=m)
update(L, R, lson, sign);
if(R>m)
update(L, R, rson, sign);
pushUp(rt, , r-l+);
pushUp(rt, , r-l+);
}
int query(int L, int R, int l, int r, int rt, int sign) {
if(L<=l&&R>=r) {
if(sign) {
return maxx[rt][];
} else {
return sum[rt][];
}
}
pushDown(rt, r-l+);
int m = l+r>>, ret = ;
if(sign) {
if(L<=m)
ret = query(L, R, lson, sign);
if(R>m)
ret = max(ret, query(L, R, rson, sign));
ret = max(ret, min(R-m, pre_max[rt<<|][])+min(m-L+, suf_max[rt<<][]));
return ret;
} else {
if(L<=m)
ret += query(L, R, lson, sign);
if(R>m)
ret += query(L, R, rson, sign);
return ret;
}
}
int main()
{
int t, n, m, sign, x, y;
cin>>t;
while(t--) {
scanf("%d%d", &n, &m);
build(, n, );
while(m--) {
scanf("%d%d%d", &sign, &x, &y);
if(sign <= ) {
update(x+, y+, , n, , sign);
} else {
cout<<query(x+, y+, , n, , sign-)<<endl;
}
}
}
}

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 线段树 区间更新 区间合并

    题意: 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 ...

  3. HDU 3397 Sequence operation(线段树)

    HDU 3397 Sequence operation 题目链接 题意:给定一个01序列,有5种操作 0 a b [a.b]区间置为0 1 a b [a,b]区间置为1 2 a b [a,b]区间0变 ...

  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. 在.NET下学习Extjs(第三个案例 Array的过滤方法(filter))

    Ext.Array.filter(Array array,Function fn,Object scope):Array array是一个数组,fn是过滤函数,scope是作用域,filter返回的是 ...

  2. .net的页面在大并发下偶尔出现503错误

    我们开发了一个回调页面,由一个工具负责调用,由于压力非常大,回调页面通过6台服务器负载均衡的: 最近业务系统又再次扩容,回调页面压力成倍增加,在高峰时间段偶尔出现了503错误. 拿到这个问题首先对系统 ...

  3. D3学习教程

    [ D3.js 入门系列 ] 入门总结 | OUR D3.JS http://www.ourd3js.com/wordpress/?p=396

  4. 好博客分享 go需要运行容器? 不需要

    http://blog.csdn.net/wsl211511/article/details/51645324 粗浅看 Tomcat中设计模式分析 http://www.infoq.com/cn/ar ...

  5. oFixed() 方法

    oFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 在本例中,我们将把数字舍入为仅有一位小数的数字: Show the number 13.37 with one decimal ...

  6. 关于函数strtok和strtok_r的使用要点和实现原理(二)

    http://www.cnblogs.com/stemon/p/4013264.html已经介绍了使用strtok函数的一些注意事项,本篇将介绍strtok的一个应用并引出strtok_r函数. 1. ...

  7. shell基础认识

    Shell 我们在终端下写命令Linux内核是看不懂的必须通过shell解释成内核可执行的代码 这就是shell(其实解释命令这只是它的一个功能模块,shell还可以用来进行程序设计) 有点类似win ...

  8. Eclipse --Type /com.xx.app/gen already exists but is not a source folde解决方案

    两种解决方案: Two actions, first: 1.Right click on the project and go to "Properties" 2.Select & ...

  9. Ajax中send方法的使用

    Ajax中send方法参数的使用 一般情况下,使用Ajax提交的参数多是些简单的字符串,可以直接使用GET方法将要提交的参数写到open方法的url参数中,此时send方法的参数为null. 例如 : ...

  10. ASP.NET Identity 系列笔记目录

    编写目的 混迹博客园已经有一段时间了,一直都是在学习各路大神的文章,自己却没有做出什么贡献,所以觉得应该写一点点内容和大家一起分享.但是本人实在才疏学浅,有心无力啊!正好最近在学习 Microsoft ...