HDOJ 3911 Black And White

来源:互联网 发布:淘宝为什么关闭弘化社 编辑:程序博客网 时间:2024/06/07 02:23

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3911

此题也是属于线段树的区间合并问题,其实就是一个单纯的区间合并问题,有关线段树区间合并问题,大家可以看一道小编写的更基础的题POJ 3667 Hotel(其实这道题也是蛮基础的)。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1const int maxn = 1000000+5;int wsum[maxn<<2],lwsum[maxn],rwsum[maxn];int bsum[maxn<<2],lbsum[maxn],rbsum[maxn];int lazy[maxn];int num[maxn];void PushUp(int m,int rt){    lwsum[rt]=lwsum[rt<<1];    lbsum[rt]=lbsum[rt<<1];    rwsum[rt]=rwsum[rt<<1|1];    rbsum[rt]=rbsum[rt<<1|1];    if(lwsum[rt] == m-(m>>1)) lwsum[rt] += lwsum[rt<<1|1];    if(lbsum[rt] == m-(m>>1)) lbsum[rt] += lbsum[rt<<1|1];        if(rwsum[rt] == (m>>1)) rwsum[rt]+=rwsum[rt<<1];    if(rbsum[rt] == (m>>1)) rbsum[rt]+=rbsum[rt<<1];    wsum[rt] = max(wsum[rt<<1],wsum[rt<<1|1]);    bsum[rt]=max(bsum[rt<<1],bsum[rt<<1|1]);    wsum[rt] = max(wsum[rt], rwsum[rt<<1] + lwsum[rt<<1|1]);    bsum[rt] = max(bsum[rt], rbsum[rt<<1] + lbsum[rt<<1|1]);}void Change(int rt){    swap(bsum[rt],wsum[rt]);    swap(lwsum[rt],lbsum[rt]);    swap(rwsum[rt],rbsum[rt]);}void PushDown(int rt){    if(lazy[rt]){        lazy[rt<<1]^=1;        lazy[rt<<1|1]^=1;        lazy[rt]=0;        Change(rt<<1);        Change(rt<<1|1);    }}void Build(int l,int r,int rt){    lazy[rt] = lbsum[rt] = rbsum[rt] = lwsum[rt] = rwsum[rt] = bsum[rt] = wsum[rt]=0;    if(l==r){        if(num[l]==1) bsum[rt] = lbsum[rt] = rbsum[rt] = 1;        else wsum[rt] = lwsum[rt] = rwsum[rt] = 1;        return ;    }    int mid = (l+r)>>1;    Build(lson);    Build(rson);    PushUp(r-l+1,rt);}void Update(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R){        lazy[rt]^=1;        Change(rt);        return ;    }    PushDown(rt);    int mid=(l+r)>>1;    if(L<=mid) Update(L,R,lson);    if(R>mid) Update(L,R,rson);    PushUp(r-l+1,rt);}int Query(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R)        return bsum[rt];    PushDown(rt);    int mid = (l+r)>>1;    if( R <= mid )         return Query(L, R, lson);    if( L > mid )        return Query(L, R, rson);    int t1 = Query(L, R, lson);    int t2 = Query(L, R, rson);    int a = min(mid-L+1, rbsum[rt<<1]);    int b = min(R-mid, lbsum[rt<<1|1]);    return max(max(t1, t2), a + b);}int main(){    int n,m,i,j,k,a,b,op;    while(scanf("%d",&n)!=EOF){        for(i=1;i<=n;i++) scanf("%d",&num[i]);        Build(1,n,1);        scanf("%d",&m);        while(m--){            scanf("%d%d%d",&op,&a,&b);             if(op==1)                 Update(a,b,1,n,1);            else{                int ans=Query(a,b,1,n,1);                printf("%d\n",ans);            }        }    }    return 0;}


0 0
原创粉丝点击