• BZOJ 1251 序列终结者


    注意pushup的时候要先判断有没有左右儿子。因为有负数,所以这个可能会出bug。

    很烦带标记的数据结构啊。。。秉承这样一个思路:只要局部的标记下方吗没有问题,整个程序应该都不会怎么出问题。

    也就是思路要顺着程序而不是顺着标记。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 100500
    #define inf 1000000007
    using namespace std;
    int n,m,root,value[maxn],size[maxn],tree[maxn][3],fath[maxn],add[maxn],rev[maxn],num[maxn];
    int k,l,r,v;
    void pushup(int now)
    {
        int ls=tree[now][1],rs=tree[now][2];
        num[now]=value[now];
        if (ls) num[now]=max(num[now],num[ls]);
        if (rs) num[now]=max(num[now],num[rs]);
        size[now]=size[ls]+size[rs]+1;
    }
    void build(int left,int right,int father)
    {
        if (left>right) return;
        int now=left;
        if (left==right)
        {
            fath[now]=father;size[now]=1;
            if (now<father) tree[father][1]=now;
            else tree[father][2]=now;
            return;
        }
        int mid=(left+right)>>1;
        now=mid;
        fath[now]=father;size[now]=1;
        if (now<father) tree[father][1]=now;
        else tree[father][2]=now;
        build(left,mid-1,mid);
        build(mid+1,right,mid);
        pushup(mid);
    }
    void pushdown(int now)
    {
        int ls=tree[now][1],rs=tree[now][2];
        if (rev[now])
        {
            rev[now]=0;rev[ls]^=1;rev[rs]^=1;
            swap(tree[now][1],tree[now][2]);
        }
        if (add[now])
        {
            if (ls) {num[ls]+=add[now];add[ls]+=add[now];value[ls]+=add[now];}
            if (rs) {num[rs]+=add[now];add[rs]+=add[now];value[rs]+=add[now];}
            add[now]=0;
        }
    }
    void rotate(int x,int &k)
    {
        int y=fath[x],z=fath[y],l,r;
        if (tree[y][1]==x) l=1;else l=2;
        r=3-l;
        if (y==k) k=x;
        else
        {
            if (tree[z][1]==y) tree[z][1]=x;
            else tree[z][2]=x;
        }
        fath[x]=z;fath[y]=x;fath[tree[x][r]]=y;
        tree[y][l]=tree[x][r];tree[x][r]=y;
        pushup(y);pushup(x);
    }
    void splay(int x,int &k)
    {
        while (x!=k)
        {
            int y=fath[x],z=fath[y];
            if (y!=k)
            {
                if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
    }
    int find(int rank,int now)
    {
        pushdown(now);
        int ls=tree[now][1],rs=tree[now][2];
        if (rank<=size[ls]) return find(rank,ls);
        else if (rank>size[ls]+1) return find(rank-size[ls]-1,rs);
        else return now;
    }
    void work1()
    {
        scanf("%d%d%d",&l,&r,&v);
        int x=find(l,root),y=find(r+2,root);
        splay(x,root);splay(y,tree[x][2]);
        int r=tree[y][1];
        add[r]+=v;value[r]+=v;num[r]+=v;
    }
    void work2()
    {
        scanf("%d%d",&l,&r);
        int x=find(l,root),y=find(r+2,root);
        splay(x,root);splay(y,tree[x][2]);
        int r=tree[y][1];rev[r]^=1;
    }
    void work3()
    {
        scanf("%d%d",&l,&r);
        int x=find(l,root),y=find(r+2,root);
        splay(x,root);splay(y,tree[x][2]);
        int r=tree[y][1];printf("%d
    ",num[r]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        root=(n+3)>>1;
        build(1,n+2,0);
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&k);
            if (k==1) work1();
            else if (k==2) work2();
            else work3();
        }
        return 0;
    }
  • 相关阅读:
    JAVA WEB开发环境与搭建
    计科院静态网页
    Python操作MySQL数据库的三种方法
    Appium环境搭建
    webstorm 默认代码格式化更改,webstorm设置prettier规则
    appium自动化环境搭建
    从事算法设计应当熟悉的资源
    redhat6如何配置本地yum源
    Windows命令查看活动连接及根据PID查看运行程序的路径、程序名等
    Tomcat与JavaWeb技术详解
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5349820.html
Copyright © 2020-2023  润新知