zoukankan      html  css  js  c++  java
  • BZOJ 4592 脑洞治疗仪

    天啦噜我自己YY的从任意起点开始的线段树上二分居然是对的。。。。

    好感动啊。

    4.7k的代码只调了一个晚上好感动。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 200500
    using namespace std;
    int n,m,sum[maxn<<2],lazy[maxn<<2],ls[maxn<<2],rs[maxn<<2],tot=0,root,l[maxn<<2],r[maxn<<2],mx[maxn<<2];
    int type,l1,r1,l2,r2;
    struct status
    {
        int mx,l,r,len;
        status (int mx,int l,int r,int len):mx(mx),l(l),r(r),len(len) {}
        status () {}
    };
    void build(int &now,int left,int right)
    {
        now=++tot;sum[now]=right-left+1;lazy[now]=-1;
        if (left==right) return;
        int mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
    }
    void pushdown(int now,int left,int right)
    {
        if (lazy[now]==-1) return;
        lazy[ls[now]]=lazy[rs[now]]=lazy[now];
        int mid=(left+right)>>1,ll=mid-left+1,rl=right-mid;
        sum[ls[now]]=lazy[ls[now]]*ll;sum[rs[now]]=lazy[rs[now]]*rl;
        l[ls[now]]=r[ls[now]]=mx[ls[now]]=(lazy[now]^1)*ll;
        l[rs[now]]=r[rs[now]]=mx[rs[now]]=(lazy[now]^1)*rl;
        lazy[now]=-1;
    }
    void pushup(int now,int left,int right)
    {
        sum[now]=sum[ls[now]]+sum[rs[now]];
        int mid=(left+right)>>1,ll=mid-left+1,rl=right-mid;
        if (mx[ls[now]]==ll) l[now]=ll+l[rs[now]];else l[now]=l[ls[now]];
        if (mx[rs[now]]==rl) r[now]=rl+r[ls[now]];else r[now]=r[rs[now]];
        mx[now]=max(r[ls[now]]+l[rs[now]],max(mx[ls[now]],mx[rs[now]]));
    }
    void modify1(int now,int left,int right,int lq,int rq,int val)
    {
        pushdown(now,left,right);
        if (left==lq && right==rq)
        {
            lazy[now]=val;sum[now]=lazy[now]*(right-left+1);
            l[now]=r[now]=mx[now]=(right-left+1)*(val^1);
            return;
        }
        int mid=(left+right)>>1;
        if (rq<=mid) modify1(ls[now],left,mid,lq,rq,val);
        else if (lq>=mid+1) modify1(rs[now],mid+1,right,lq,rq,val);
        else modify1(ls[now],left,mid,lq,mid,val),modify1(rs[now],mid+1,right,mid+1,rq,val);
        pushup(now,left,right);
    }
    int warn=0;
    int modify3(int now,int left,int right,int k)
    {
        warn++;
        pushdown(now,left,right);
        int kk=right-left+1-sum[now];
        if (k>=kk)
        {
            sum[now]=right-left+1;lazy[now]=1;
            mx[now]=l[now]=r[now]=0;
            return kk;
        }
        if (left==right)
        {
            sum[now]=1;mx[now]=l[now]=r[now]=0;
            return 1;
        }
        int mid=(left+right)>>1,rr=mid-left+1-sum[ls[now]],ret=0;
        if (k<=rr) ret=modify3(ls[now],left,mid,k);
        else 
        {
            sum[ls[now]]=mid-left+1;lazy[ls[now]]=1;
            mx[ls[now]]=l[ls[now]]=r[ls[now]]=0;
            ret=rr+modify3(rs[now],mid+1,right,k-rr);
        }
        pushup(now,left,right);return ret;
    }
    int modify2(int now,int left,int right,int l,int r,int k)
    {
        warn++;
        pushdown(now,left,right);
        if ((left==l) && (right==r)) return modify3(now,left,right,k);
        int mid=(left+right)>>1,ret=0;
        if (r<=mid) 
        {
            if (mid-left+1-sum[ls[now]]>0)
                ret=modify2(ls[now],left,mid,l,r,k);
        }
        else if (l>=mid+1) 
        {
            if (right-mid-sum[rs[now]]>0)
                ret=modify2(rs[now],mid+1,right,l,r,k);
        }
        else
        {
            if (mid-left+1-sum[ls[now]]) ret=modify2(ls[now],left,mid,l,mid,k);
            if ((k>ret) && (right-mid-sum[rs[now]])) ret+=modify2(rs[now],mid+1,right,mid+1,r,k-ret);
        }
        pushup(now,left,right);return ret;
    }
    status merge(status x,status y)
    {
        status ret=status(0,0,0,0);
        if (x.mx==x.len) ret.l=x.len+y.l;else ret.l=x.l;
        if (y.mx==y.len) ret.r=y.len+x.r;else ret.r=y.r;
        ret.mx=max(x.r+y.l,max(x.mx,y.mx));
        ret.len=x.len+y.len;
        return ret;
    }
    int ask1(int now,int left,int right,int l,int r)
    {
        pushdown(now,left,right);
        if (left==l && right==r) return sum[now];
        int mid=(left+right)>>1;
        if (r<=mid) return ask1(ls[now],left,mid,l,r);
        else if (l>=mid+1) return ask1(rs[now],mid+1,right,l,r);
        else return ask1(ls[now],left,mid,l,mid)+ask1(rs[now],mid+1,right,mid+1,r); 
    }
    status ask2(int now,int left,int right,int lq,int rq)
    {
        pushdown(now,left,right);
        if ((left==lq) && (right==rq)) return status(mx[now],l[now],r[now],right-left+1);
        int mid=(left+right)>>1;
        if (rq<=mid) return ask2(ls[now],left,mid,lq,rq);
        else if (lq>=mid+1) return ask2(rs[now],mid+1,right,lq,rq);
        else return merge(ask2(ls[now],left,mid,lq,mid),ask2(rs[now],mid+1,right,mid+1,rq));
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        build(root,1,n);    
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&type,&l1,&r1);
            if (!type) modify1(root,1,n,l1,r1,0);
            else if (type==1)
            {
                warn=0;
                scanf("%d%d",&l2,&r2);
                int ret=ask1(root,1,n,l1,r1);
                modify1(root,1,n,l1,r1,0);
                if (ret) {int kr=modify2(root,1,n,l2,r2,ret);kr++;}
            }
            else printf("%d
    ",ask2(root,1,n,l1,r1).mx);
        }
        return 0;
    }
  • 相关阅读:
    LeetCode "Super Ugly Number" !
    LeetCode "Count of Smaller Number After Self"
    LeetCode "Binary Tree Vertical Order"
    LeetCode "Sparse Matrix Multiplication"
    LeetCode "Minimum Height Tree" !!
    HackerRank "The Indian Job"
    HackerRank "Poisonous Plants"
    HackerRank "Kundu and Tree" !!
    LeetCode "Best Time to Buy and Sell Stock with Cooldown" !
    HackerRank "AND xor OR"
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6421741.html
Copyright © 2011-2022 走看看