hdu 3911 线段树基本功 区间合并
2012-04-03 10:07
357 查看
可以用来锻炼线段树基本功
这种题思路基本不用怎么想,固定好代码框架,往里面填代码就好了,但要绝对仔细
因为有异或操作,所以要把白色和黑色的信息都记录下来,在更新的时候可以互换
View Code
这种题思路基本不用怎么想,固定好代码框架,往里面填代码就好了,但要绝对仔细
因为有异或操作,所以要把白色和黑色的信息都记录下来,在更新的时候可以互换
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; }
相关文章推荐
- HDU 3911 Black And White (线段树区间合并 + lazy标记)
- HDU 3911 Black And White(线段树区间合并)
- hdu 3911 线段树的区间合并
- hdu 3911 线段树+区间合并
- HDU 3911 线段树区间合并
- HDU 3911 线段树区间合并、异或取反操作
- HDU 3911 线段树区间合并+异或操作
- HDU 3911 Black And White(线段树区间合并+lazy操作)
- hdu 3911 black and white 线段树区间合并
- hdu 3911 Black And White 线段树区间合并
- 【HDU - 3911】Black And White 【线段树+区间操作+区间合并】
- HDU 3911 Black And White(线段树区间合并+lazy操作)
- hdu 3911 Black And White 区间合并 线段树
- hdu 3308 LCIS(线段树区间合并)
- hdu--3308 LCIS(线段树+区间合并)
- HDU-1540 Tunnel Warfare 线段树 区间合并
- hdu 3308(线段树的区间合并)
- HDU 3308 LCIS 线段树 区间合并 入门题
- HDU 4718 The LCIS on the Tree (树链剖分 + 线段树区间合并)
- HDU 4553 线段树双关键字区间合并