zoukankan      html  css  js  c++  java
  • 【bzoj1500】维修数列——splay

    splay的高级题目,有splay的全部操作,然而本蒟蒻竟不自量力地把这道题作为splay的入门题,然后就学(mi)习(man)了一个星期……

    第一次是对着cyc的模版码的,万分感谢><

    第二次就自己码了一个小时(弱......)

    就作为一个splay学习的模版吧!

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    const int maxn=5e5+10,inf=0x3f3f3f3f;
    using namespace std;
    int n,m,root,a[maxn],A[maxn];
    int g[maxn],en[maxn],R[maxn],L[maxn],M[maxn],sum[maxn],s[maxn];
    int t[maxn][2],f[maxn]; 
    queue<int>q;
    int read()
    {
        char c=getchar();int ans=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
        return ans*f;
    }
    void count(int x)
    {
        L[x]=max(L[t[x][0]],sum[t[x][0]]+A[x]+max(0,L[t[x][1]]));
        R[x]=max(R[t[x][1]],sum[t[x][1]]+A[x]+max(0,R[t[x][0]]));
        M[x]=max(R[t[x][0]],0)+A[x]+max(0,L[t[x][1]]);
        M[x]=max(M[x],max(M[t[x][0]],M[t[x][1]]));
        sum[x]=sum[t[x][0]]+A[x]+sum[t[x][1]];
        s[x]=s[t[x][0]]+1+s[t[x][1]];
    }
    void pushdown(int x)
    {
        if(g[x])
        {
            g[t[x][0]]^=1;g[t[x][1]]^=1;
            swap(R[t[x][0]],L[t[x][0]]);
            swap(L[t[x][1]],R[t[x][1]]);
            swap(t[x][0],t[x][1]);
            g[x]=0;
        }
        if(en[x])
        {
            if(t[x][0])
            {
                en[t[x][0]]=1;
                A[t[x][0]]=A[x];
                sum[t[x][0]]=s[t[x][0]]*A[x];
                L[t[x][0]]=R[t[x][0]]=M[t[x][0]]=A[x]>0?sum[t[x][0]]:A[x];
            }
            if(t[x][1])
            {
                en[t[x][1]]=1;
                A[t[x][1]]=A[x];
                sum[t[x][1]]=s[t[x][1]]*A[x];
                L[t[x][1]]=R[t[x][1]]=M[t[x][1]]=A[x]>0?sum[t[x][1]]:A[x];
            }
            en[x]=0;
        }
    }
    void rotate(int x)
    {
        int k=x==t[f[x]][1];
        int y=f[x];
        t[y][k]=t[x][!k];f[t[x][!k]]=y;t[x][!k]=y;
        if(f[y])t[f[y]][y==t[f[y]][1]]=x;f[x]=f[y];f[y]=x;
        L[x]=L[y];R[x]=R[y];M[x]=M[y];sum[x]=sum[y];s[x]=s[y];
        count(y);
    }
    void splay(int x,int r)
    {
        for(int fa=f[r];f[x]!=fa;)
        {
            if(f[f[x]]==fa){rotate(x);break;}
            int X=x==t[f[x]][1],Y=f[x]==t[f[f[x]]][1];
            if(X^Y)rotate(x),rotate(x);
                else rotate(f[x]),rotate(x);
        }
    }
    int node(int fa,int num)
    {
        int sz=q.front();q.pop();
        A[sz]=L[sz]=R[sz]=M[sz]=sum[sz]=num;
        s[sz]=1;t[sz][0]=t[sz][1]=g[sz]=en[sz]=0;
        f[sz]=fa;
        return sz;
    }
    void build(int fa,int &x,int l,int r)
    {
        if(l>r)return;
        int mid=(l+r)>>1;
        x=node(fa,a[mid]);
        build(x,t[x][0],l,mid-1);
        build(x,t[x][1],mid+1,r);
        count(x);
    }
    void find(int &x,int k)
    {
        for(int i=x;i;)
        {
            pushdown(i);
            if(k<=s[t[i][0]]){i=t[i][0];continue;}
            if(k==s[t[i][0]]+1){splay(i,x);x=i;break;}
            k-=s[t[i][0]]+1;i=t[i][1];
        }
    }
    void insert()
    {
        int l=read(),k=read();
        for(int i=1;i<=k;i++)a[i]=read();
        int r=0;
        build(0,r,1,k);
        find(root,l+1);find(t[root][1],1);
        t[t[root][1]][0]=r;f[r]=t[root][1];
        count(t[root][1]);count(root);
    }
    void erase(int x)
    {
        if(x)
        {
            q.push(x);
            erase(t[x][0]);
            erase(t[x][1]);
        }
    }
    void del()
    {
        int l=read(),k=read();
        find(root,l);find(t[root][1],k+1);
        erase(t[t[root][1]][0]);
        t[t[root][1]][0]=0;
        count(t[root][1]);count(root);
    }
    void cover()
    {
        int l=read(),k=read(),num=read();
        find(root,l);find(t[root][1],k+1);
        int y=t[t[root][1]][0];
        en[y]=1;A[y]=num;
        sum[y]=s[y]*A[y];
        R[y]=L[y]=M[y]=A[y]>0?sum[y]:A[y];
        count(t[root][1]);count(root);
    }
    void turn()
    {
        int l=read(),k=read();
        find(root,l);find(t[root][1],k+1);
        int y=t[t[root][1]][0];
        g[y]^=1;
        swap(R[y],L[y]);
        count(t[root][1]);count(root);
    }
    void get_sum()
    {
        int l=read(),k=read();
        find(root,l);find(t[root][1],k+1);
        printf("%d
    ",sum[t[t[root][1]][0]]);
    }
    void get_m()
    {
        int sz=s[root];
        find(root,1);find(t[root][1],sz-1);
        printf("%d
    ",M[t[t[root][1]][0]]);
    }
    int main()
    {
        n=read();m=read();
        a[0]=a[n+1]=0;root=0;
        L[0]=R[0]=M[0]=-inf;
        for(int i=1;i<=maxn;i++)q.push(i);
        for(int i=1;i<=n;i++)a[i]=read();
        build(0,root,0,n+1);
        char str[20];
        for(int i=1;i<=m;i++)
        {
            scanf("%s",str);
            if(str[2]=='S')insert();
            else if(str[2]=='L')del();
            else if(str[2]=='K')cover();
            else if(str[2]=='V')turn();
            else if(str[2]=='T')get_sum();
            else if(str[2]=='X')get_m();
        }
        return 0;
    }
    bzoj1500
  • 相关阅读:
    Ext学习之路——Ext.application
    MVVM模式理解
    MVC和MVVM的区别
    如何才能通俗易懂的解释js里面的‘闭包’?
    【移动端】用Cordova将vue项目打包成app
    【vue源码】js中的with语句
    【移动端】移动端点击可点击元素时,出现蓝色默认背景色
    【人脸识别】纯前端实现人脸融合-调用Face++的人脸融合API接口实现
    new Function()语法
    Element-ui 自定义下拉框,实现选择图片并且回显图片
  • 原文地址:https://www.cnblogs.com/JKAI/p/7067212.html
Copyright © 2011-2022 走看看