您的位置:首页 > 编程语言 > Go语言

hdu3911 区间线段树

2014-06-18 03:55 218 查看
写的比较难看了 不过区间就是应该这么写没错,关键是异或操作

要不产生冲突就要记录标记 然后标记的标记就是没标记= =

写的不好 实际上用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  algorithm