• HDU 3397 Sequence operation 线段树 成段更新 区间合并


    比较综合的题。

    两个标记  setv,xorr。setv的优先级高于xorr,当一个节点获得一个setv时,他之前的xorr要清除。

    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<cmath>
    #include<climits>
    #include<string>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    #define pb(a) push_back(a)
    #define INF 0x1f1f1f1f
    #define lson idx<<1,l,mid
    #define rson idx<<1|1,mid+1,r
    #define PI  3.1415926535898
    template<class T> T min(const T& a,const T& b,const T& c) {
        return min(min(a,b),min(a,c));
    }
    template<class T> T max(const T& a,const T& b,const T& c) {
        return max(max(a,b),max(a,c));
    }
    void debug() {
    #ifdef ONLINE_JUDGE
    #else
    
        freopen("d:\in.txt","r",stdin);
        freopen("d:\out1.txt","w",stdout);
    #endif
    }
    int getch() {
        int ch;
        while((ch=getchar())!=EOF) {
            if(ch!=' '&&ch!='
    ')return ch;
        }
        return EOF;
    }
    const int maxn=100100;
    struct  node
    {
        int num,lc[2],pre[2],suf[2],len;
    };
    int xorr[maxn<<2];
    int setv[maxn<<2];
    node tree[maxn<<2];
    void Merge(node &q,node &a,node &b)
    {
        q.num=a.num+b.num;
        q.len=a.len+b.len;
        for(int i=0;i<2;i++)
        {
            q.lc[i]=max(a.lc[i],b.lc[i],a.suf[i]+b.pre[i]);
            q.pre[i]=a.pre[i]==a.len?a.pre[i]+b.pre[i]:a.pre[i];
            q.suf[i]=b.suf[i]==b.len?b.suf[i]+a.suf[i]:b.suf[i];
        }
    }
    void PushDown(int idx)
    {
        if(setv[idx]!=-1)
        {
            int &v=setv[idx];
            int ls=idx<<1,rs=idx<<1|1;
            setv[ls]=setv[rs]=v;
            xorr[ls]=xorr[rs]=0;
    
            //lson
            tree[ls].lc[v]=tree[ls].pre[v]=tree[ls].suf[v]=tree[ls].len;
            tree[ls].lc[!v]=tree[ls].pre[!v]=tree[ls].suf[!v]=0;
            tree[ls].num=v==1?tree[ls].len:0;
    
            //rson
            tree[rs].lc[v]=tree[rs].pre[v]=tree[rs].suf[v]=tree[rs].len;
            tree[rs].lc[!v]=tree[rs].pre[!v]=tree[rs].suf[!v]=0;
            tree[rs].num=v==1?tree[rs].len:0;
    
            v=-1;
        }
        if(xorr[idx]!=0)
        {
            //lson
            xorr[idx<<1]^=1;
            tree[idx<<1].num=tree[idx<<1].len-tree[idx<<1].num;
            swap(tree[idx<<1].lc[0],tree[idx<<1].lc[1]);
            swap(tree[idx<<1].pre[0],tree[idx<<1].pre[1]);
            swap(tree[idx<<1].suf[0],tree[idx<<1].suf[1]);
            // rson
            xorr[idx<<1|1]^=1;
            tree[idx<<1|1].num=tree[idx<<1|1].len-tree[idx<<1|1].num;
            swap(tree[idx<<1|1].lc[0],tree[idx<<1|1].lc[1]);
            swap(tree[idx<<1|1].pre[0],tree[idx<<1|1].pre[1]);
            swap(tree[idx<<1|1].suf[0],tree[idx<<1|1].suf[1]);
    
            xorr[idx]=0;
        }
    }
    int build(int idx,int l,int r)
    {
        xorr[idx]=0;
        setv[idx]=-1;
        if(l==r)
        {
            int v;
            scanf("%d",&v);
            tree[idx].len=1;
            tree[idx].num=v==1?1:0;
            tree[idx].lc[v]=tree[idx].pre[v]=tree[idx].suf[v]=1;
            tree[idx].lc[!v]=tree[idx].pre[!v]=tree[idx].suf[!v]=0;
            return 0;
        }
        int mid=(r+l)>>1;
        build(lson);
        build(rson);
        Merge(tree[idx],tree[idx<<1],tree[idx<<1|1]);
        return 0;
    }
    int update(int idx,int l,int r,int tl,int tr,int op)
    {
        if(tl<=l&&tr>=r)
        {
            if(op==2)
            {
                xorr[idx]^=1;
                tree[idx].num=tree[idx].len-tree[idx].num;
                swap(tree[idx].lc[0],tree[idx].lc[1]);
                swap(tree[idx].pre[0],tree[idx].pre[1]);
                swap(tree[idx].suf[0],tree[idx].suf[1]);
            }else
            {
                xorr[idx]=0;
                setv[idx]=op;
                tree[idx].num=op==1?tree[idx].len:0;
                tree[idx].lc[op]=tree[idx].pre[op]=tree[idx].suf[op]=tree[idx].len;
                tree[idx].lc[!op]=tree[idx].pre[!op]=tree[idx].suf[!op]=0;
            }
            return 0;
        }
        PushDown(idx);
        int mid=(r+l)>>1;
        if(tl<=mid)update(lson,tl,tr,op);
        if(tr>mid)update(rson,tl,tr,op);
        Merge(tree[idx],tree[idx<<1],tree[idx<<1|1]);
        return 0;
    }
    node query(int idx,int l,int r,int tl,int tr)
    {
        if(tl<=l&&tr>=r)return tree[idx];
        PushDown(idx);
        int mid=(r+l)>>1;
        node q;
        if(tl<=mid&&tr>mid)
        {
            node a=query(lson,tl,tr);
            node b=query(rson,tl,tr);
            Merge(q,a,b);
        }else if(tl<=mid)q=query(lson,tl,tr);
        else q=query(rson,tl,tr);
        return q;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        for(int ca=1;ca<=t;ca++)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            build(1,0,n-1);
            for(int i=1;i<=m;i++)
            {
                int op,a,b;
                scanf("%d%d%d",&op,&a,&b);
                if(op<=2)update(1,0,n-1,a,b,op);
                else
                {
                    node q=query(1,0,n-1,a,b);
                    printf("%d
    ",op==3?q.num:q.lc[1]);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Go语言对etcd的基本操作
    etcd命令行基本操作
    etcd集群部署
    第二十一天python3 python的正则表达式re模块学习
    第二十天python3 正则表达式
    jenkins多分支构建选择
    第十九天python3 json和messagepack
    华为交换机设置ntp时间同步
    交换机端口光衰问题排查
    第十八天python3 序列化和反序列化
  • 原文地址:https://www.cnblogs.com/BMan/p/3297044.html
Copyright © 2020-2023  润新知