zoukankan      html  css  js  c++  java
  • HDU3991:Black and White

    浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3911

    用线段树维护六个信息,分别是区间最长子段,最左边连续的最长段,最右边连续的最长段,然后分(0)(1)分别处理出来。询问的时候因为会先访问最左边的段,然后依次往右走,所以开一个全局变量存上一段最右一段(1)有多长,然后和当前段合并起来更新答案就行。

    时间复杂度:(O(mlogn))

    空间复杂度:(O(n))

    代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
     
    const int maxn=1e5+5;
     
    int a[maxn];
    int n,m,ans,mx;
     
    int read() {
        int x=0,f=1;char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
     
    struct tree_node {
        int mx[2],lft[2],rgt[2];
    };
     
    struct segment_tree {
        bool rev[maxn<<2];
        tree_node tree[maxn<<2];
         
        void updata(int p,int l,int r) {
            int mid=(l+r)>>1;
            for(int i=0;i<2;i++) {
                tree[p].mx[i]=max(tree[p<<1].rgt[i]+tree[p<<1|1].lft[i],max(tree[p<<1].mx[i],tree[p<<1|1].mx[i]));
                if(tree[p<<1].lft[i]==mid-l+1)tree[p].lft[i]=tree[p<<1].lft[i]+tree[p<<1|1].lft[i];
                else tree[p].lft[i]=tree[p<<1].lft[i];
                if(tree[p<<1|1].rgt[i]==r-mid)tree[p].rgt[i]=tree[p<<1].rgt[i]+tree[p<<1|1].rgt[i];
                else tree[p].rgt[i]=tree[p<<1|1].rgt[i];
            }
        }
         
        void add_tag(int p) {
            rev[p]^=1;
            swap(tree[p].mx[0],tree[p].mx[1]);
            swap(tree[p].lft[0],tree[p].lft[1]);
            swap(tree[p].rgt[0],tree[p].rgt[1]);
        }
     
        void push_down(int p) {
            if(rev[p]) {
                add_tag(p<<1);
                add_tag(p<<1|1);
                rev[p]=0;
            }
        }
     
        void build(int p,int l,int r) {
            rev[p]=0;
            for(int i=0;i<2;i++)
                tree[p].mx[i]=tree[p].lft[i]=tree[p].rgt[i]=0;//多组数据要记得清空
            if(l==r) {
                tree[p].mx[a[l]]=1;
                tree[p].lft[a[l]]=1;
                tree[p].rgt[a[l]]=1;
                return;
            }
            int mid=(l+r)>>1;
            build(p<<1,l,mid);
            build(p<<1|1,mid+1,r);
            updata(p,l,r);
        }
     
        void rever(int p,int l,int r,int L,int R) {
            if(L<=l&&r<=R) {
                add_tag(p);
                return;
            }
            int mid=(l+r)>>1;push_down(p);
            if(L<=mid)rever(p<<1,l,mid,L,R);
            if(R>mid)rever(p<<1|1,mid+1,r,L,R);
            updata(p,l,r);
        }
         
        void query(int p,int l,int r,int L,int R) {
            if(L<=l&&r<=R) {
                ans+=tree[p].lft[1];
                mx=max(mx,max(tree[p].mx[1],ans));
                if(tree[p].lft[1]!=r-l+1)ans=tree[p].rgt[1];
                return;
            }
            int mid=(l+r)>>1;push_down(p);
            if(L<=mid)query(p<<1,l,mid,L,R);
            if(R>mid)query(p<<1|1,mid+1,r,L,R);
        }
    }T;
     
    int main() {
        while(~scanf("%d",&n)) {
            for(int i=1;i<=n;i++)
                a[i]=read();
            T.build(1,1,n);m=read();
            for(int i=1;i<=m;i++) {
                int opt=read(),l=read(),r=read();
                if(opt==1)T.rever(1,1,n,l,r);
                else {
                    ans=mx=0;
                    T.query(1,1,n,l,r);
                    printf("%d
    ",mx);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    树上差分
    Java学习笔记(二)事件监听器
    Java学习笔记(三)Java2D组件
    1066. Root of AVL Tree (25)
    有一种蓝,是神往,是心醉,是心伤
    软考论文的六大应对策略V1.0
    iOS 图形编程总结
    【悼鲁迅】诗一首
    【秋游】诗一首
    【游普罗旺斯薰衣草庄园】诗一首
  • 原文地址:https://www.cnblogs.com/AKMer/p/9950663.html
Copyright © 2011-2022 走看看