题目链接

给出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. list 去重复

    两层遍历,如果后面的元素和前面的相同,就把后面的删除,达到去重复的目的. 比较的元素可以是list中含有的任意唯一性的元素. for(int x = 0;x < xglist.size()-1; ...

  2. 利用VS自带的命令行工具查看和生产PublicKeyToken (转)

    使用VS2013(或其他版本)命令行工具,键入:SN -T C:\*****.dll 就会显示出该dll具体的PublicKeyToken数值. 如果该程序集没有强命 名,则不会有PublicKeyT ...

  3. OCP prepare 20140701

    1. rman的完全备份,和不完全备份 Oracle 数据库可以实现数据库不完全恢复与完全恢复.完全恢复是将数据库恢复到最新时刻,也就是无损恢复,保证数据库无丢失的恢复.而不完全恢复则是根据需要特意将 ...

  4. C# 调用其他的动态库开发应注意的问题

    1.背景 程序开发语言可以说是五花八门,这就引出了一个新问题 ,不同语言开发的系统进行对接时相关调用的问题. 下面我主要说一下我自己在做接口开发时遇到的问题及解决方法仅供参考,我使用的C#开发进行对接 ...

  5. 学习使用GitHub(一)--之入门

    因为经常Windows和linux系统交替的使用,在实验室一台电脑,在家一台电脑,自己的电脑和实验室的电脑上面的代码往往没法同步,以前由于种种原因(其实就是懒,没有学习GitHub这样的代码管理工具) ...

  6. zabbix监控服务器部署

    1.服务器安装lamp环境 [root@monitor ~]# yum  install gcc gcc-c++ autoconf httpd php mysql mysql-server php-m ...

  7. Iso language code table之(软件国际化)

    ISO 639是用来区分所有已知的语言规范的术语.每种语言都分配两个字母(639-1)或三个英文字母(639-2和639-3),小写字母的缩写,修订后的版本命名的.该系统是非常有用的语言学家和人类学家 ...

  8. Chrome disable adobe flash player

    New tab and input : chrome://plugins/ so easy~!

  9. vb6.0 时间日期

    使用year(now)可以得到4位数的年    你还可以用Format来得到, 还有FormatDateTime 下面两种都是一样的结果:  FormatDateTime(now,vbLongDate ...

  10. 原版Windows XP Pro With SP3 VOL MSDN简体中文专业版

    2008年5月2日,微软推出Windows XP Pro With SP3 VOL MSDN x86 32位简体中文专业版,这是最经典也是我最喜爱的操作系统之一.在MSDN(微软开发者网络)的网站上查 ...