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

hdu 3397 Sequence operation(线段树,lazy,区间合并)

2014-05-15 13:29 423 查看
hdu 3397 Sequence operation

线段树lazy和区间合并结合的一个题,相当于几个题集中到一起嘛,分开想就好了

0,1,2操作都要lazy,2的异或操作找到每一只含1或只含0的区间进行取反

3的查询没啥好说的,最基础的求和查询

4的查询要用到区间合并的操作,需要注意的是查询区间跨左右儿子时要考虑跨区间的连续为1的段要在查询区间内

#include<cstdio>
#include<cstring>
#define MAXN 100005
#define lch p<<1
#define rch p<<1|1
//#define mid (t[p].l+t[p].r)>>1
struct node
{
int l,r;
int cover;
int sum;
int mx,lmx,rmx;
//int getlen() {return r-l+1;}
int len;
}t[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 p)
{
t[p].sum=t[lch].sum+t[rch].sum;

t[p].mx=max(t[lch].mx,t[rch].mx);
t[p].mx=max(t[p].mx,t[lch].rmx+t[rch].lmx);

t[p].lmx=t[lch].lmx;
if(t[lch].lmx==t[lch].len) t[p].lmx+=t[rch].lmx;

t[p].rmx=t[rch].rmx;
if(t[rch].rmx==t[rch].len) t[p].rmx+=t[lch].rmx;
}
void construct(int l,int r,int p)
{
t[p].len=r-l+1;
t[p].l=l,t[p].r=r;
t[p].cover=-1;
if(l==r)
{
scanf("%d",&t[p].mx);
t[p].cover=t[p].lmx=t[p].rmx=t[p].sum=t[p].mx;
return ;
}
int m=(t[p].l+t[p].r)>>1;
construct(l,m,lch);
construct(m+1,r,rch);
pushup(p);
}
void refresh(int p)
{
if(t[p].cover==0)
t[p].mx=t[p].lmx=t[p].rmx=t[p].sum=0;
else
t[p].mx=t[p].lmx=t[p].rmx=t[p].sum=t[p].len;
}
void pushdown(int p)
{
t[lch].cover=t[p].cover;
t[rch].cover=t[p].cover;
refresh(lch);
refresh(rch);
t[p].cover=-1;
}
void modify(int l,int r,int p,int op)
{
if(t[p].l==l&&t[p].r==r)
{
t[p].cover=op;
refresh(p);
return ;
}
if(t[p].cover!=-1) pushdown(p);
int m=(t[p].l+t[p].r)>>1;
if(r<=m) modify(l,r,lch,op);
else if(l>m) modify(l,r,rch,op);
else modify(l,m,lch,op),modify(m+1,r,rch,op);
pushup(p);
}
void modify_xor(int l,int r,int p)
{
if(t[p].l==l&&t[p].r==r&&(t[p].sum==0||t[p].sum==t[p].len))
{
if(t[p].sum) t[p].cover=0;
else t[p].cover=1;
refresh(p);
return ;
}
if(t[p].cover!=-1) pushdown(p);
int m=(t[p].l+t[p].r)>>1;
if(r<=m) modify_xor(l,r,lch);
else if(l>m) modify_xor(l,r,rch);
else modify_xor(l,m,lch),modify_xor(m+1,r,rch);
pushup(p);
}
int query(int l,int r,int p)
{
if(t[p].l==l&&t[p].r==r)
return t[p].sum;
if(t[p].cover!=-1) pushdown(p);
int m=(t[p].l+t[p].r)>>1;
if(r<=m) return query(l,r,lch);
else if(l>m) return query(l,r,rch);
else return query(l,m,lch)+query(m+1,r,rch);
}
int query_len(int l,int r,int p)
{
if(t[p].l==l&&t[p].r==r)
return t[p].mx;
if(t[p].cover!=-1) pushdown(p);
int m=(t[p].l+t[p].r)>>1;
if(r<=m) return query_len(l,r,lch);
else if(l>m) return query_len(l,r,rch);
else
{
int ans=max(query_len(l,m,lch),query_len(m+1,r,rch));
int lans=min(t[lch].rmx,t[lch].r-l+1),
rans=min(t[rch].lmx,r-t[rch].l+1);
return ans=max(ans,lans+rans);
}
}
int main()
{
int cas,n,m,op,l,r;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&m);
construct(0,n-1,1);
while(m--)
{
scanf("%d%d%d",&op,&l,&r);
if(op==0)
modify(l,r,1,0);
else if(op==1)
modify(l,r,1,1);
else if(op==2)
modify_xor(l,r,1);
else if(op==3)
printf("%d\n",query(l,r,1));
else
printf("%d\n",query_len(l,r,1));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息