您的位置:首页 > 其它

HDU 3397 线段树 较麻烦

2013-09-04 16:15 239 查看
3911的升级版

同时要做两种LAZY操作,一定要先做COVER,否则会WA,因为COVER可以覆盖之前的XOR

#include "stdio.h"
#include "string.h"
#include "math.h"
#include "stdlib.h"
#include "algorithm"
using namespace std;

struct comp
{
int l,r,mid;
int l1,l0; // 记录区间内从最左端起连续1和0个数
int r1,r0; // 记录区间内从最右端起连续1和0个数
int m1,m0; // 记录区间内最长连续1和0个数
int cover; // lazy操作的覆盖
int xor; // lazy操作的变换
int sum; // 区间内1的总数
} data[300005];

int max(int a,int b)
{
if (a<b) return b; else return a;
}
void PushUp(int k)
{
int ll,rr;
ll=data[k*2].r-data[k*2].l+1;
rr=data[k*2+1].r-data[k*2+1].l+1;

data[k].sum=data[k*2].sum+data[k*2+1].sum;

data[k].l1=data[k*2].l1;
if (data[k].l1==ll) data[k].l1+=data[k*2+1].l1;
data[k].l0=data[k*2].l0;
if (data[k].l0==ll) data[k].l0+=data[k*2+1].l0;

data[k].r1=data[k*2+1].r1;
if (data[k].r1==rr) data[k].r1+=data[k*2].r1;
data[k].r0=data[k*2+1].r0;
if (data[k].r0==rr) data[k].r0+=data[k*2].r0;

data[k].m1=max(  max(data[k*2].m1,data[k*2+1].m1) ,  data[k*2].r1+data[k*2+1].l1);
data[k].m0=max(  max(data[k*2].m0,data[k*2+1].m0) ,  data[k*2].r0+data[k*2+1].l0);
}

void build(int l,int r,int k)
{
int x;
data[k].l=l; data[k].r=r;
data[k].mid=(l+r)/2;
data[k].xor=0;
data[k].cover=-1;

if (l==r)
{
scanf("%d",&x);
if (x==1)
{
data[k].l1=data[k].r1=data[k].m1=1;
data[k].l0=data[k].r0=data[k].m0=0;
data[k].sum=1;
data[k].cover=1;
}
else
{
data[k].l1=data[k].r1=data[k].m1=0;
data[k].l0=data[k].r0=data[k].m0=1;
data[k].sum=0;
data[k].cover=0;
}
return ;
}

build(l,data[k].mid,k*2);
build(data[k].mid+1,r,k*2+1);

PushUp(k);
}

void PushDown(int k) // 重点是两种LAZY操作的顺序,必须先做COVER操作
{
int ll,rr;
if (data[k].l==data[k].r) return ;
ll=data[k*2].r-data[k*2].l+1;
rr=data[k*2+1].r-data[k*2+1].l+1;

if (data[k].cover!=-1)
{
data[k*2].cover=data[k*2+1].cover=data[k].cover;
data[k*2].xor=data[k*2+1].xor=0;
if (data[k].cover==1)
{
data[k*2].sum=ll;
data[k*2+1].sum=rr;

data[k*2].l1=data[k*2].r1=data[k*2].m1=ll;
data[k*2].l0=data[k*2].r0=data[k*2].m0=0;

data[k*2+1].l1=data[k*2+1].r1=data[k*2+1].m1=rr;
data[k*2+1].l0=data[k*2+1].r0=data[k*2+1].m0=0;
}
if (data[k].cover==0)
{
data[k*2].sum=data[k*2+1].sum=0;

data[k*2].l1=data[k*2].r1=data[k*2].m1=0;
data[k*2].l0=data[k*2].r0=data[k*2].m0=ll;

data[k*2+1].l1=data[k*2+1].r1=data[k*2+1].m1=0;
data[k*2+1].l0=data[k*2+1].r0=data[k*2+1].m0=rr;
}
data[k].cover=-1;
}

if (data[k].xor%2==1)
{
data[k].xor=0;
data[k*2].xor++;
data[k*2+1].xor++;

data[k*2].sum=ll-data[k*2].sum;
data[k*2+1].sum=rr-data[k*2+1].sum;

swap(data[k*2].l1,data[k*2].l0);
swap(data[k*2].r1,data[k*2].r0);
swap(data[k*2].m1,data[k*2].m0);

swap(data[k*2+1].l1,data[k*2+1].l0);
swap(data[k*2+1].r1,data[k*2+1].r0);
swap(data[k*2+1].m1,data[k*2+1].m0);

}

}

void update(int l,int r,int k,int op)
{
int le;
PushDown(k);
if (data[k].l==l && data[k].r==r )
{
le=data[k].r-data[k].l+1;
if (op==0)
{
data[k].cover=0;
data[k].sum=0;
data[k].l1=data[k].r1=data[k].m1=0;
data[k].l0=data[k].r0=data[k].m0=le;
data[k].xor=0;
}
if (op==1)
{
data[k].cover=1;
data[k].sum=le;
data[k].l1=data[k].r1=data[k].m1=le;
data[k].l0=data[k].r0=data[k].m0=0;
data[k].xor=0;
}
if (op==2)
{
if (data[k].cover!=-1) data[k].cover=(data[k].cover+1)%2;
data[k].sum=le-data[k].sum;
swap(data[k].l1,data[k].l0);
swap(data[k].r1,data[k].r0);
swap(data[k].m1,data[k].m0);
data[k].xor++;
}
return ;
}

if (r<=data[k].mid) update(l,r,k*2,op);
else
if (l>data[k].mid) update(l,r,k*2+1,op);
else
{
update(l,data[k].mid,k*2,op);
update(data[k].mid+1,r,k*2+1,op);
}

PushUp(k);
}

int query(int l,int r,int k,int op)
{
int aa,bb,ll,rr;
if (data[k].l==l && data[k].r==r)
{
if (op==3) return data[k].sum;
else return data[k].m1;
}

PushDown(k);

if (r<=data[k].mid) return query(l,r,k*2,op);
else
if (l>data[k].mid) return query(l,r,k*2+1,op);
else
{
if (op==3) return query(l,data[k].mid,k*2,op)+query(data[k].mid+1,r,k*2+1,op);
else
{
aa=query(l,data[k].mid,k*2,op);
bb=query(data[k].mid+1,r,k*2+1,op);

ll=data[k*2].r1;
if (ll>data[k*2].r-l+1) ll=data[k*2].r-l+1;

rr=data[k*2+1].l1;
if (rr>r-data[k*2+1].l+1) rr=r-data[k*2+1].l+1;

return max(max(aa,bb),ll+rr);
}
}
}
int main()
{
int t,n,m,a,b,c;

scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
build(1,n,1);
while (m--)
{
scanf("%d%d%d",&a,&b,&c);
b++;
c++;
if (a<=2) update(b,c,1,a);
else
printf("%d\n",query(b,c,1,a));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: