您的位置:首页 > 其它

HDU 3911 Black And White

2011-08-07 12:55 281 查看
有原题的题。

自己写的时候,一直超时。悲催啊。

然后,上网看了下别人的解题报告,发现需要一个标记,用来表示是否需要翻转。这样,就不用每次都更新到连续的区间。(避免复杂度变高)

果断,给力啊。

#include <iostream>
using namespace std;

#define MAXN 100100

#define LL(x) x<<1
#define RR(x) x<<1|1
#define MID(a,b) ((a+b)>>1)

struct node{
int l,r,cov,tag;
int lval0,cval0,rval0;
int lval1,cval1,rval1;
}tree[MAXN*4];

int nu[MAXN];

inline int max(int a,int b)
{
return a>b?a:b;
}

inline int min(int a,int b)
{
return a<b?a:b;
}

inline int len(int num)
{
return tree[num].r - tree[num].l + 1;
}

void update(int num)
{
tree[num].lval0 = tree[LL(num)].lval0;
tree[num].rval0 = tree[RR(num)].rval0;
if(tree[num].lval0==len(LL(num)))
tree[num].lval0 += tree[RR(num)].lval0;
if(tree[num].rval0==len(RR(num)))
tree[num].rval0 += tree[LL(num)].rval0;
tree[num].cval0 = max(max(tree[LL(num)].cval0,tree[RR(num)].cval0),tree[LL(num)].rval0+tree[RR(num)].lval0);

tree[num].lval1 = tree[LL(num)].lval1;
tree[num].rval1 = tree[RR(num)].rval1;
if(tree[num].lval1==len(LL(num)))
tree[num].lval1 += tree[RR(num)].lval1;
if(tree[num].rval1==len(RR(num)))
tree[num].rval1 += tree[LL(num)].rval1;
tree[num].cval1 = max(max(tree[LL(num)].cval1,tree[RR(num)].cval1),tree[LL(num)].rval1+tree[RR(num)].lval1);

if(tree[num].cval0 == len(num))
tree[num].cov = 0;
else if(tree[num].cval1 == len(num))
tree[num].cov = 1;
else
tree[num].cov = -1;
}

void build(int l,int r,int num)
{
tree[num].l = l;
tree[num].r = r;
tree[num].cov = -1;
tree[num].tag = 0;
if(l==r)
{
tree[num].cov = nu[l];
tree[num].lval0=tree[num].cval0=tree[num].rval0=(1^nu[l]);
tree[num].lval1=tree[num].cval1=tree[num].rval1=(0^nu[l]);
return;
}
int mid = MID(l,r);
build(l,mid,LL(num));
build(mid+1,r,RR(num));
update(num);
}

void swap(int num)
{
int tmp;
tmp = tree[num].cval0;
tree[num].cval0 = tree[num].cval1;
tree[num].cval1 = tmp;
tmp = tree[num].lval0;
tree[num].lval0 = tree[num].lval1;
tree[num].lval1 = tmp;
tmp = tree[num].rval0;
tree[num].rval0 = tree[num].rval1;
tree[num].rval1 = tmp;
if(tree[num].cov!=-1)
tree[num].cov^=1;
}

void change(int l,int r,int num)
{
if(tree[num].l==l&&tree[num].r==r)
{
swap(num);
tree[num].tag^=1;
return;
}
if(tree[num].tag)
{
swap(LL(num));
swap(RR(num));
tree[LL(num)].tag^=1;
tree[RR(num)].tag^=1;
tree[num].tag=0;
}
int mid=MID(tree[num].l,tree[num].r);
if(r<=mid)
change(l,r,LL(num));
else if(l>mid)
change(l,r,RR(num));
else
{
change(l,mid,LL(num));
change(mid+1,r,RR(num));
}
update(num);
}

int query(int l,int r,int num)
{
if(tree[num].cov==1)
{
return (r-l+1);
}
else if(tree[num].cov==0)
{
return 0;
}
if(tree[num].l==l&&tree[num].r==r)
{
return tree[num].cval1;
}
if(tree[num].tag)
{
swap(LL(num));
swap(RR(num));
tree[LL(num)].tag^=1;
tree[RR(num)].tag^=1;
tree[num].tag=0;
}
int mid = MID(tree[num].l,tree[num].r);
if(r<=mid)
return query(l,r,LL(num));
else if(l>mid)
return query(l,r,RR(num));
else
{
return max(max(query(l,mid,LL(num)),query(mid+1,r,RR(num))),min(mid-l+1,tree[LL(num)].rval1)+min(r-mid,tree[RR(num)].lval1));
}
}

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