hdu3911 区间线段树
2014-06-18 03:55
218 查看
写的比较难看了 不过区间就是应该这么写没错,关键是异或操作
要不产生冲突就要记录标记 然后标记的标记就是没标记= =
写的不好 实际上用0,1标记更加好 直接可以 lazy^1
还有一种传统写法 可以结构体里面多放点
要不产生冲突就要记录标记 然后标记的标记就是没标记= =
写的不好 实际上用0,1标记更加好 直接可以 lazy^1
#include<iostream> #include<stdio.h> #include<cstdio> using namespace std; #define ls (rt<<1) #define rs (rt<<1|1) #define mid ((l+r)>>1) #define maxn 222222 int l0[maxn<<2],m0[maxn<<2],r0[maxn<<2]; int l1[maxn<<2],m1[maxn<<2],r1[maxn<<2]; int ox[maxn<<2]; int n,m,x,a,b; void up(int rt,int l,int r) { l0[rt]=l0[ls];m0[rt]=max(m0[ls],m0[rs]);r0[rt]=r0[rs]; l1[rt]=l1[ls];m1[rt]=max(m1[ls],m1[rs]);r1[rt]=r1[rs]; if(l0[ls]==(mid-l+1)) l0[rt]+=l0[rs]; if(l1[ls]==(mid-l+1)) l1[rt]+=l1[rs]; if(r0[rs]==(r-mid)) r0[rt]+=r0[ls]; if(r1[rs]==(r-mid)) r1[rt]+=r1[ls]; m0[rt]=max(r0[ls]+l0[rs],m0[rt]); m1[rt]=max(r1[ls]+l1[rs],m1[rt]); } void build(int rt,int l,int r) { ox[rt]=-1; if(l==r) { scanf("%d",&x); l1[rt]=r1[rt]=m1[rt]=x; l0[rt]=r0[rt]=m0[rt]=x^1; return ; } build(ls,l,mid); build(rs,mid+1,r); up(rt,l,r); } void down(int rt) { if(ox[rt]!=-1) { ox[ls]=(ox[ls]==-1?1:-1); ox[rs]=(ox[rs]==-1?1:-1); ox[rt]=-1; swap(l0[ls],l1[ls]); swap(r0[ls],r1[ls]); swap(l0[rs],l1[rs]); swap(r0[rs],r1[rs]); swap(m0[ls],m1[ls]); swap(m0[rs],m1[rs]); } } void ins(int rt,int l,int r,int L,int R) { if(L<=l&&r<=R){ ox[rt]=(ox[rt]==1?-1:1); swap(l0[rt],l1[rt]); swap(r0[rt],r1[rt]); swap(m0[rt],m1[rt]); return ; } down(rt); if(L<=mid)ins(ls,l,mid,L,R); if(mid<R)ins(rs,mid+1,r,L,R); up(rt,l,r); } int tmp,tmpl,tmpr; int query(int rt,int l,int r,int L,int R) { if(L<=l&&r<=R) return m1[rt]; down(rt); if(mid>=R)tmp=query(ls,l,mid,L,R); else if(mid<L)tmp=query(rs,mid+1,r,L,R); else{ tmp=max(query(ls,l,mid,L,R),query(rs,mid+1,r,L,R)); tmpl=min(mid-L+1,r1[ls]); tmpr=min(R-mid,l1[rs]); tmp=max(tmp,tmpl+tmpr); } return tmp; } void gao() { while(~scanf("%d",&n)) { build(1,1,n); scanf("%d",&m); for(int i=0;i<m;++i) { scanf("%d%d%d",&x,&a,&b); if(x){ ins(1,1,n,a,b); } else{ printf("%d\n",query(1,1,n,a,b)); } } } } int main() { gao(); return 0; }
还有一种传统写法 可以结构体里面多放点
#include<iostream> #include<stdio.h> #include<cstdio> using namespace std; #define ls (rt<<1) #define rs (rt<<1|1) #define mid ((l+r)>>1) #define maxn 222222 int l0[maxn<<2],m0[maxn<<2],r0[maxn<<2]; int l1[maxn<<2],m1[maxn<<2],r1[maxn<<2]; int ox[maxn<<2]; int n,m,x,a,b; void up(int rt,int l,int r) { l0[rt]=l0[ls];m0[rt]=max(m0[ls],m0[rs]);r0[rt]=r0[rs]; l1[rt]=l1[ls];m1[rt]=max(m1[ls],m1[rs]);r1[rt]=r1[rs]; if(l0[ls]==(mid-l+1)) l0[rt]+=l0[rs]; if(l1[ls]==(mid-l+1)) l1[rt]+=l1[rs]; if(r0[rs]==(r-mid)) r0[rt]+=r0[ls]; if(r1[rs]==(r-mid)) r1[rt]+=r1[ls]; m0[rt]=max(r0[ls]+l0[rs],m0[rt]); m1[rt]=max(r1[ls]+l1[rs],m1[rt]); } void build(int rt,int l,int r) { ox[rt]=-1; if(l==r) { scanf("%d",&x); l1[rt]=r1[rt]=m1[rt]=x; l0[rt]=r0[rt]=m0[rt]=x^1; return ; } build(ls,l,mid); build(rs,mid+1,r); up(rt,l,r); } void down(int rt) { if(ox[rt]!=-1) { ox[ls]=(ox[ls]==-1?1:-1); ox[rs]=(ox[rs]==-1?1:-1); ox[rt]=-1; swap(l0[ls],l1[ls]); swap(r0[ls],r1[ls]); swap(l0[rs],l1[rs]); swap(r0[rs],r1[rs]); swap(m0[ls],m1[ls]); swap(m0[rs],m1[rs]); } } void ins(int rt,int l,int r,int L,int R) { if(L<=l&&r<=R){ ox[rt]=(ox[rt]==1?-1:1); swap(l0[rt],l1[rt]); swap(r0[rt],r1[rt]); swap(m0[rt],m1[rt]); return ; } down(rt); if(L<=mid)ins(ls,l,mid,L,R); if(mid<R)ins(rs,mid+1,r,L,R); up(rt,l,r); } int tmp,tmpl,tmpr; int query(int rt,int l,int r,int L,int R) { if(L<=l&&r<=R) return m1[rt]; down(rt); if(mid>=R)tmp=query(ls,l,mid,L,R); else if(mid<L)tmp=query(rs,mid+1,r,L,R); else{ tmp=max(query(ls,l,mid,L,R),query(rs,mid+1,r,L,R)); tmpl=min(mid-L+1,r1[ls]); tmpr=min(R-mid,l1[rs]); tmp=max(tmp,tmpl+tmpr); } return tmp; } void gao() { while(~scanf("%d",&n)) { build(1,1,n); scanf("%d",&m); for(int i=0;i<m;++i) { scanf("%d%d%d",&x,&a,&b); if(x){ ins(1,1,n,a,b); } else{ printf("%d\n",query(1,1,n,a,b)); } } } } int main() { gao(); return 0; }
相关文章推荐
- hdu3911 线段树的区间更新
- hdu3911(线段树,区间合并,延迟标记)
- hdu3911 Black And White(线段树区间合并)
- hdu3911 Black And White 【线段树+区间异或操作】
- hdu3911 Black And White 线段树区间合并
- hdu3911线段树区间合并操作
- POJ - 3162 Walking Race 【树上最远距离 + 线段树处理区间最值 + 尺取法 】
- 线段树区间更新延迟标记
- HDU 1698 【线段树区间更新】
- 线段树区间更新&&求和poj3486
- HDU - 1698 D - Just a Hook (线段树区间更新)
- HDU 5893 List wants to travel (树链剖分,线段树区间合并)
- 线段树(二)区间最值
- 线段树区间更新Thermal Death of the Universe
- hdu4027Can you answer these queries?【线段树区间更新区间求和】
- POJ 3468 线段树(区间更新)
- 线段树单点更新+区间更新
- hdu3308LCIS(线段树区间合并)
- kuangbin专题七 : B题 :HDU 1754 I Hate It(线段树单点更新区间查询最值)
- hdu 3397 Sequence Operation 线段树维护区间前后缀和,求子区间连续最值