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;
    }
  • 相关阅读:
    二读《活着》有感
    Linux系统上安装JDK和Tomcat服务器
    在阿里云服务器上安装完成并启动Tomcat后,通过http不能访问--解决办法
    安装JDK出现错误:-bash: /usr/java/jdk1.7.0_71/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory解决办法
    python结巴(jieba)分词
    mysql数据库优化
    ansible常见模块
    CentOS6.5 64位下安装部署Ansible
    [Python] 利用commands模块执行Linux shell命令
    python迭代器
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6421741.html
Copyright © 2011-2022 走看看