SPOJ 4487. Can you answer these queries VI(GSS6) splay

    一个序列,四中操作,在x前插入y;删除位置x的数;把位置x的数改成y;查询区间[x,y]的最大子段和。算是维护数列的简化版吧,但时间卡的要死=...输入挂+输出挂都用上了才勉强卡过去....

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
typedef int ll;
const int maxn=200000+10000;


int a[maxn];
int root,tot,n,m;
int p,q,tt,t,k,r;


inline int getint() {
    int res;
     char ch;
     bool neg;
     while (ch = getchar(), !isdigit(ch) && ch != '-')
         ;
     if (ch == '-') {
         res = 0;
         neg = true;
     } else {
         res = ch - '0';
         neg = false;
     }
     while (ch = getchar(), isdigit(ch))
         res = res * 10 + ch - '0';
     return neg ? -res : res;
}

inline char CHAR() {
     char res;
     while (res = getchar(), !isalpha(res))
         ;
     return res;
}

inline void printf_(int num){
    bool flag=false;
    if(num<0){
        putchar('-');
        num=-num;
    }
    int ans[10],top=0;
    while(num!=0){
        ans[top++]=num%10;
        num/=10;
    }
    if(top==0)
        putchar('0');
    for(int i=top-1;i>=0;i--){
        char ch=ans[i]+'0';
        putchar(ch);
    }
    putchar('\n');
}

struct splaytree
{
    ll key[maxn],sub[maxn],suff[maxn],pref[maxn],sum[maxn];
    int pre[maxn],ch[maxn][2];
    int stk[maxn];
    int top;
    int size[maxn];


    inline void pushup(int r)
    {
        if (r==0) return;
        size[r]=size[ch[r][0]]+1+size[ch[r][1]];
        sum[r]=sum[ch[r][0]]+key[r]+sum[ch[r][1]];
        pref[r]=max(pref[ch[r][0]],sum[ch[r][0]]+key[r]+max(0,pref[ch[r][1]]));
        suff[r]=max(suff[ch[r][1]],sum[ch[r][1]]+key[r]+max(0,suff[ch[r][0]]));
        sub[r]=max(0,suff[ch[r][0]])+key[r]+max(0,pref[ch[r][1]]);
        sub[r]=max(sub[r],max(sub[ch[r][0]],sub[ch[r][1]]));
    }

    inline void rotate(int x,int kind)
    {
        int y=pre[x];
        ch[y][!kind]=ch[x][kind];
        pre[ch[x][kind]]=y;
        if (pre[y])
        {
            ch[pre[y]][ch[pre[y]][1]==y]=x;
        }
        pre[x]=pre[y];
        ch[x][kind]=y;
        pre[y]=x;
        pushup(y);
    }
    inline void splay(int x,int tgt)
    {
        while(pre[x]!=tgt)
        {
            int y=pre[x];

            if (pre[pre[x]]==tgt)
            {
                rotate(x,ch[pre[x]][0]==x);
            }
            else
            {
                int kind=ch[pre[y]][0]==y;
                if (ch[y][kind]==x)
                {
                    rotate(x,kind^1);
                    rotate(x,kind);
                }
                else
                {
                    rotate(y,kind);
                    rotate(x,kind);
                }
            }
        }
        pushup(x);
        if (tgt==0) root=x;
    }
    inline int select(int k,int tgt)
    {
        int rt=root;
        while(true)
        {
            if (k<=size[ch[rt][0]]) rt=ch[rt][0];
            else if (k==size[ch[rt][0]]+1) break;
            else k-=(size[ch[rt][0]]+1),rt=ch[rt][1];
        }
        if (tgt>=0) splay(rt,tgt);
        return rt;

    }
     inline void newnode(int &r,int father,ll k)
    {
//        if (top)
//        {
//            r=stk[top--];
//        }
//        else r=++tot;
        r=++tot;
        pre[r]=father;
        size[r]=1;
        key[r]=k;
        sum[r]=suff[r]=pref[r]=sub[r]=k;
        ch[r][0]=ch[r][1]=0;
    }
    inline void build(int l,int r,int &x,int rt)
    {
        if (l>r) return;
        int m=(l+r)>>1;
        newnode(x,rt,a[m]);
        build(l,m-1,ch[x][0],x);
        build(m+1,r,ch[x][1],x);
        pushup(x);
    }
    inline void init()
    {
        tot=root=0;
        top=0;
        newnode(root,0,-(1<<30));
        newnode(ch[root][1],root,-(1<<30));
        suff[0]=pref[0]=sub[0]=-(1<<30);
        suff[1]=pref[1]=sub[1]=-(1<<30);
        suff[2]=pref[2]=sub[2]=-(1<<30);

        build(1,n,ch[ch[root][1]][0],ch[root][1]);
        pushup(ch[root][1]);
        pushup(root);
    }


    inline void insert(int posi,int num)
    {
        ll c;
        select(posi+1,0);
        select(posi+2,root);
        int tp;
        tp=getint();
        newnode(ch[ch[root][1]][0],ch[root][1],tp);
        pushup(ch[root][1]);
        pushup(root);
    }
    inline void del(int posi)
    {
        select(posi,0);
        select(posi+2,root);
        int k=ch[ch[root][1]][0];
//        recover(k);
        pre[k]=0;
        ch[ch[root][1]][0]=0;
        pushup(ch[root][1]);
        pushup(root);
    }
    inline void recover(int r)
    {
        if (!r) return;
        stk[++top]=r;
        recover(ch[r][0]);
        recover(ch[r][1]);
    }
    inline int Max_sum(int l,int r)
    {
        select(l,0);
        select(r+2,root);
        return sub[ch[ch[root][1]][0]];
    }
    inline void modify(int posi,int x)
    {
        select(posi+1,0);
        key[root]=x;
        pushup(root);
       
    }
}spt;
char cmd[30];
int x,y,z;
ll c;
int main()
{
   //freopen("in.txt","r",stdin);
    n=getint();
    for (int i=1; i<=n; i++)
    {
        a[i]=getint();
    }
    spt.init();
    m=getint();
    char cc;
    for (int i=1; i<=m; i++)
    {
//        cout<<ch[0][0]<<"---"<<ch[0][1]<<"--"<<pre[0]<<"hit----\n";
        cc=CHAR();
        if (cc=='I')
        {
            x=getint();
            spt.insert(x-1,1);
        }
        else
        if (cc=='Q')
        {
            x=getint();
            y=getint();
            int ans=spt.Max_sum(x,y);
            printf_(ans); 
//            printf("%d\n",ans);
        }
        else
        if (cc=='R')
        {
            x=getint();
            y=getint();
            spt.modify(x,y);
        }
        else
        if (cc=='D')
        {
            x=getint();
            spt.del(x);
        }
    }
    return 0;
}


你可能感兴趣的:(SPOJ 4487. Can you answer these queries VI(GSS6) splay)