您的位置:首页 > 产品设计 > UI/UE

HDU 3397 Sequence operation (线段树区间合并入门)

2015-08-10 12:50 441 查看
维护8个数组,区间和,区间连续1和0的最多的范围,左区间最多连续1和0的范围,右区间最多连续1和0的范围,

和一个懒标记数组c[],-2为全0,-1为全1,1为互换(就是^1)。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>

#define lson l, m , rt<<1
#define rson m+1,r, rt<<1|1
using namespace std;
const int maxn = 100005;

int n,q,a[maxn];

struct SegTree{
int sum[maxn<<2],ls_1[maxn<<2],ms_1[maxn<<2],rs_1[maxn<<2],
ls_0[maxn<<2],ms_0[maxn<<2],rs_0[maxn<<2],c[maxn<<2];

void push_up(int l,int r,int rt){
int m = (l + r) >> 1;
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
ms_1[rt] = max(max(ms_1[rt<<1],ms_1[rt<<1|1]),rs_1[rt<<1]+ls_1[rt<<1|1]);
ms_0[rt] = max(max(ms_0[rt<<1],ms_0[rt<<1|1]),rs_0[rt<<1]+ls_0[rt<<1|1]);
ls_1[rt] = ls_1[rt<<1] == m-l+1 ? ls_1[rt<<1]+ls_1[rt<<1|1] : ls_1[rt<<1];
rs_1[rt] = rs_1[rt<<1|1] == r-m ? rs_1[rt<<1|1]+rs_1[rt<<1] : rs_1[rt<<1|1];
ls_0[rt] = ls_0[rt<<1] == m-l+1 ? ls_0[rt<<1]+ls_0[rt<<1|1] : ls_0[rt<<1];
rs_0[rt] = rs_0[rt<<1|1] == r-m ? rs_0[rt<<1|1]+rs_0[rt<<1] : rs_0[rt<<1|1];
return;
}
void push_down(int l,int r,int rt){
if(c[rt] == 0) return;
if(l != r){
if(c[rt] != 1) c[rt<<1] = c[rt<<1|1] = c[rt];
else{
c[rt<<1] = c[rt<<1] == -2 ? -1 : c[rt<<1] == -1 ? -2 : c[rt<<1]^1 ;
c[rt<<1|1] = c[rt<<1|1] == -2 ? -1 : c[rt<<1|1] == -1 ? -2 : c[rt<<1|1]^1;
}
}
if(c[rt] == -2){
sum[rt] = ms_1[rt] = ls_1[rt] = rs_1[rt] = 0;
ms_0[rt] = ls_0[rt] = rs_0[rt] = r-l+1;
}
if(c[rt] == -1){
sum[rt] = ms_1[rt] = ls_1[rt] = rs_1[rt] = r-l+1;
ms_0[rt] = ls_0[rt] = rs_0[rt] = 0;
}
if(c[rt] == 1){
sum[rt] = (r-l+1) - sum[rt];
swap(ls_0[rt],ls_1[rt]);swap(ms_0[rt],ms_1[rt]);swap(rs_0[rt],rs_1[rt]);
}
c[rt] = 0;
}
void build(int l,int r,int rt){
c[rt] = 0;
if(l == r){
if(a[l]){
sum[rt] = ms_1[rt] = ls_1[rt] = rs_1[rt] = 1;
ms_0[rt] = ls_0[rt] = rs_0[rt] = 0;
}else{
sum[rt] = ms_1[rt] = ls_1[rt] = rs_1[rt] = 0;
ms_0[rt] = ls_0[rt] = rs_0[rt] = 1;
}
return;
}
int m = (l + r) >> 1;
build(lson);build(rson);
push_up(l,r,rt);
}
void update(int a,int b,int x,int l,int r,int rt){
push_down(l,r,rt);
if(l > b || r < a) return;
if(a <= l && r <= b){
c[rt] = x;
push_down(l,r,rt);
return;
}
int m = (l + r) >> 1;
update(a,b,x,lson);update(a,b,x,rson);
push_up(l,r,rt);
}
int query(int a,int b,int op,int l,int r,int rt){
push_down(l,r,rt);
if(l > b || r < a) return 0;
if(a <= l && r <= b) return op ? ms_1[rt] : sum[rt];
int m = (l + r) >> 1;
if(op){
int o1 = 0,o2 = 0,o3 = 0;
o1 = query(a,b,op,lson);o2 = query(a,b,op,rson);
if(a <= m && m < b){
o3 = min(m-a+1,rs_1[rt<<1]) + min(b-m,ls_1[rt<<1|1]);
}
return max(max(o1,o2),o3);
}else return query(a,b,op,lson) + query(a,b,op,rson);
}
void debug(int l,int r,int rt){
push_down(l,r,rt);
if(l == r){
printf("%d ",sum[rt]);
return;
}
int m = (l + r) >> 1;
debug(lson);debug(rson);
}
}sol;

int main(){
int cas;
scanf("%d",&cas);
while(cas--){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sol.build(1,n,1);
int op,aa,bb;
while(q--){
scanf("%d%d%d",&op,&aa,&bb);
if(op == 0) sol.update(aa+1,bb+1,-2,1,n,1);
else if(op == 1) sol.update(aa+1,bb+1,-1,1,n,1);
else if(op == 2) sol.update(aa+1,bb+1,1,1,n,1);
else if(op == 3) printf("%d\n",sol.query(aa+1,bb+1,0,1,n,1));
else printf("%d\n",sol.query(aa+1,bb+1,1,1,n,1));
//sol.debug(1,n,1);putchar('\n');
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: