• 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;
    }
    
  • 相关阅读:
    HTML DOM 06 节点关系
    HTML DOM 05 事件(三)
    HTML DOM 05 事件(二)
    HTML DOM 05 事件(一)
    html DOM 04 样式
    html DOM 03 节点的属性
    html DOM 02 获取节点
    html DOM 01 节点概念
    JavaScript 29 计时器
    JavaScript 28 弹出框
  • 原文地址:https://www.cnblogs.com/AKMer/p/9950663.html
Copyright © 2020-2023  润新知