题目链接

给出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. linux循环递归设置权限

    这里给出一个循环递归得到对文件夹和文件分别有效的设置方法: find /path -type f -exec chmod 644 {} \; #对目录和子目录里的文件 find /path -type ...

  2. C#XML操作详解

     添加引用 using System.Xml; 创建XML文件 XmlDocument xmldoc=new XmlDocument(); //加入XML的声明段落:<?xmlversion=& ...

  3. 20151217--Ajax的一点补充

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 比callback更简洁的链式执行promise

    promise自己理解的也不够深刻,具体知识点不在这里细说了 直接上个例子,清晰明了,自己去悟吧 <script type="text/javascript"> //模 ...

  5. 在windows 8.1 64位配置python和opencv

    之前在linux下安装python和opencv及相关的库,都可以直接命令行操作.最近需要在windows下配置一下,查了一些资料,发现网上有很多关于python和opencv的配置,但由于不同版本问 ...

  6. python----设置默认编码

    问题:python的默认编码是ascii.在处理中文的时候可能会出现乱码的情况:这个时候我们就需要把编码设置为对应的编码了. 解决方案: 对python文件的头部做如下修改 import sys re ...

  7. Sql优化(三) 关于oracle的并发

    Oracle的并发技术可以将一个大任务分解为多个小任务由多个进程共同完成.合理地使用并发可以充分利用系统资源,提高效率.一. 并发的种类Parallel queryParallel DML(PDML) ...

  8. System.DateTime的一些格式

    //2008年4月24日     System.DateTime.Now.ToString("D"); //2008-4-24     System.DateTime.Now.To ...

  9. JS中String添加trim()方法

    这么牛的JS竟然还要自己封装trim方法. 下面利用prototype和正则表达式的添加方式添加trim(): <script language="javascript"&g ...

  10. 详述USB OTG发展及协议标准

    USB On-The-Go 扩大了USB 的应用领域,将USB 从传统的PC 与外设通讯的模式,扩展到移动电子和嵌入式领域中,抛开主机PC,实现通常的外设与外设之间点对点(Point to Point ...