hdu 3911 线段树基本功 区间合并
可以用来锻炼线段树基本功
这种题思路基本不用怎么想,固定好代码框架,往里面填代码就好了,但要绝对仔细
因为有异或操作,所以要把白色和黑色的信息都记录下来,在更新的时候可以互换
View Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 111111;
int sum[maxn<<2];
int lb[maxn<<2],rb[maxn<<2];
int col[maxn<<2];
int wm[maxn<<2];
int wl[maxn<<2];
int wr[maxn<<2];
int max(int a,int b){
return a>b?a:b;
}
int Min(int a,int b){
return a<b?a:b;
}
void pushup(int m,int rt){
wl[rt]=wl[rt<<1];
lb[rt]=lb[rt<<1];
wr[rt]=wr[rt<<1|1];
rb[rt]=rb[rt<<1|1];
if(wl[rt]==m-(m>>1)) wl[rt]+=wl[rt<<1|1];
if(lb[rt]==m-(m>>1)) lb[rt]+=lb[rt<<1|1];
if(wr[rt]==(m>>1)) wr[rt]+=wr[rt<<1];
if(rb[rt]==(m>>1)) rb[rt]+=rb[rt<<1];
wm[rt]=max(wm[rt<<1],wm[rt<<1|1]);
sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
wm[rt] = max(wm[rt], wr[rt<<1] + wl[rt<<1|1]);
sum[rt] = max(sum[rt], rb[rt<<1] + lb[rt<<1|1]);
}
void make(int rt){
swap(sum[rt],wm[rt]);
swap(wl[rt],lb[rt]);
swap(wr[rt],rb[rt]);
}
void pushdown(int rt){
if(col[rt]){
col[rt<<1]^=1;
col[rt<<1|1]^=1;
col[rt]=0;
make(rt<<1);
make(rt<<1|1);
}
}
int num[100001];
void build(int l,int r,int rt){
col[rt]=lb[rt]=rb[rt]=wl[rt]=wr[rt]=sum[rt]=wm[rt]=0;
if(l==r){
if(num[l]==1) sum[rt]=lb[rt]=rb[rt]=1;
else {
wm[rt]=wl[rt]=wr[rt]=1;
}return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(r-l+1,rt);
}
void update(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
col[rt]^=1;
make(rt);
return ;
}
pushdown(rt);
int m=(l+r)>>1;
if(L<=m) update(L,R,lson);
if(R>m) update(L,R,rson);
pushup(r-l+1,rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R) {
return sum[rt];
}
pushdown(rt);
int m=(l+r)>>1;
if ( R <= m )
return query(L, R, lson);
if ( L > m )
return query(L, R, rson);
int t1 = query(L, R, lson);
int t2 = query(L, R, rson);
int a = Min(m-L+1, rb[rt<<1]);
int b = Min(R-m, lb[rt<<1|1]);
return max(max(t1, t2), a + b);
}
int main(){
int n,m,i,j,k,a,b,op;
while(scanf("%d",&n)!=EOF){
for(i=1;i<=n;i++) scanf("%d",&num[i]);
build(1,n,1);
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&op,&a,&b);
if(op==1)
update(a,b,1,n,1);
else {
int ans=query(a,b,1,n,1);
printf("%d\n",ans);
}
}
}
return 0;
}