GSS6 4487. Can you answer these queries VI splay

GSS6 Can you answer these queries VI

给出一个数列,有以下四种操作:

I x y: 在位置x插入y。
D x  : 删除位置x上的元素。
R x y: 把位置x用y取替。
Q x y: 输出区间[x,y]的最大字段和。

 

分析:

其实这题是BZOJ 1500 [NOI2005]维修数列这题的简化版。

使用splay来做非常简单。

我的做法增加一个虚拟节点在数列的最开始处,增加两个虚拟节点在最后,这是为了方便在数列最后插入的操作。

splay网上的资料比较多,其实splay比sbt、avl都简单。这里有我的一份总结,并且有一些资料: splay总结

 

囧,我写的splay太慢了,最后上网搜了一个IO外挂才过了。

 

 

#include <set>

#include <map>

#include <list>

#include <cmath>

#include <queue>

#include <stack>

#include <string>

#include <vector>

#include <cstdio>

#include <cstring>

#include <iostream>

#include <algorithm>



using namespace std;



typedef long long ll;

typedef unsigned long long ull;



#define debug puts("here")

#define rep(i,n) for(int i=0;i<n;i++)

#define rep1(i,n) for(int i=1;i<=n;i++)

#define REP(i,a,b) for(int i=a;i<=b;i++)

#define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)

#define pb push_back

#define RD(n) scanf("%d",&n)

#define RD2(x,y) scanf("%d%d",&x,&y)

#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)

#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)

#define All(vec) vec.begin(),vec.end()

#define MP make_pair

#define PII pair<int,int>

#define PQ priority_queue

#define cmax(x,y) x = max(x,y)

#define cmin(x,y) x = min(x,y)

#define Clear(x) memset(x,0,sizeof(x))

/*



#pragma comment(linker, "/STACK:1024000000,1024000000")



int size = 256 << 20; // 256MB

char *p = (char*)malloc(size) + size;

__asm__("movl %0, %%esp\n" :: "r"(p) );



*/



/******** program ********************/



const int MAXN = 210005;

const int INF = 1e9;



int ch[MAXN][2],fa[MAXN],sz[MAXN],root,tot;

int sum[MAXN],val[MAXN];

int lmax[MAXN],rmax[MAXN],mmax[MAXN];

int a[MAXN];





#define lx ch[x][0]

#define rx ch[x][1]

#define px fa[x]



#define ly ch[y][0]

#define ry ch[y][1]

#define py fa[y]





#define lz ch[z][0]

#define rz ch[z][1]

#define pz fa[z]



#define rt ch[root][1]

#define lrt ch[rt][0]

#define rrt ch[rt][1]





// 调试

void dfs(int x){

    if(x){

        int a = ch[x][0];

        int b = ch[x][1];

        dfs(a);

        printf("x:  %3d %3d %3d  ",x,a,b);

        printf("val:  %3d\n",val[x]);

        dfs(b);

    }

}



void gdb(){

    puts("\n---------------------");

    dfs(root);

    puts("---------------------\n");

}



inline void update(int x){

    if(!x)return;

    sz[x] = sz[lx]+sz[rx]+1;

    sum[x] = sum[lx]+sum[rx]+val[x];

    lmax[x] = max( lmax[lx] , sum[lx]+val[x]+max(0,lmax[rx]) );

    rmax[x] = max( rmax[rx] , sum[rx]+val[x]+max(0,rmax[lx]) );

    mmax[x] = max( mmax[lx] , mmax[rx] );

    mmax[x] = max( mmax[x] , max(0,lmax[rx])+val[x]+max(0,rmax[lx]) );

}



inline int sgn(int x){

    return ch[px][1]==x;

}



inline void setc(int y,int d,int x){

    ch[y][d] = x;

    px = y;

}



inline void rot(int x,int d){

    int y = px;

    int z = py;

    setc(y,!d,ch[x][d]);

    if(z)   setc(z,sgn(y),x);

    fa[x] = z;

    setc(x,d,y);

    update(y);

}



inline void splay(int x,int goal=0){

    if(!x)return;

    while(px!=goal){

        int y = px;

        int z = py;

        if(z==goal){

            rot(x,!sgn(x));

            break;

        }

        if(lz==y){

            if(ly==x)

                rot(y,1),rot(x,1);

            else

                rot(x,0),rot(x,1);

        }

        else{

            if(ry==x)

                rot(y,0),rot(x,0);

            else

                rot(x,1),rot(x,0);

        }

    }

    update(x);

    if(goal==0)

        root = x;

}



inline void newNode(int &x,int y,int v){

    x = ++ tot;

    sz[x] = 1;

    ch[x][0] = ch[x][1] = 0;

    val[x] = sum[x] = lmax[x] = rmax[x] = mmax[x] = v;

    fa[x] = y;

}



inline void build(int &x,int y,int l,int r){

    if(l>r) return;

    int mid = (l+r)>>1;

    newNode(x,y,a[mid]);

    build(lx,x,l,mid-1);

    build(rx,x,mid+1,r);

    update(x);

}



inline int getKth(int x,int k){

    while( sz[lx]+1 != k ){

        if(k<=sz[lx])x = lx;

        else{

            k -= sz[lx]+1;

            x = rx;

        }

    }

    return x;

}



inline void splay(int x,int y,int ok){

    splay( getKth(root,x) );

    splay( getKth(root,y) , root );

}



inline void Int(int &num){

    char in;

    bool neg=false;

    while(((in=getchar()) > '9' || in<'0') && in!='-') ;

    if(in=='-'){

        neg=true;

        while((in=getchar()) >'9' || in<'0');

    }

    num=in-'0';

    while(in=getchar(),in>='0'&&in<='9')

        num*=10,num+=in-'0';

    if(neg)

        num=0-num;

}



char Char() {

     char res;

     while (res = getchar(), !isalpha(res));

     return res;

}



char s[MAXN<<2];

int cur;



inline int Int(){

    int ans = 0;

    bool ok = 0 , f = 0;

    for(;s[cur];cur++){

        if(s[cur]==' '){

            if(f)break;

            continue;

        }f = true;

        if(s[cur]=='-')ok = true;

        else ans = ans*10+s[cur]-'0';

    }

    if(ok)ans = -ans;

    return ans;

}



int main(){



#ifndef ONLINE_JUDGE

    freopen("sum.in","r",stdin);

    //freopen("sum.out","w",stdout);

#endif



    int n,m,x,y;

    char op;



    RD(n);

    rep1(i,n)

        Int(a[i]);

    lmax[0] = mmax[0] = rmax[0] = -INF;



    a[++n] = INF; // 补一个虚拟节点,方便在最后插入



    newNode(root,0,-INF);

    newNode(ch[root][1],root,INF);



    update(rt);

    update(root);



    build(lrt,rt,1,n);

    update(rt);

    update(root);



    RD(m);

    while(m--){

        op = Char();

        Int(x);

        if(op=='I'){

            Int(y);

            splay(x,x+1,0);

            newNode(lrt,rt,y);

            update(rt);

            update(root);

        }else if(op=='D'){

            splay(x,x+2,0);

            fa[lrt] = 0;

            lrt = 0;

        }else if(op=='R'){

            Int(y);

            splay(x,x+2,0);

            fa[lrt] = 0;

            lrt = 0;

            newNode(lrt,rt,y);

        }else{

            Int(y);

            splay(x,y+2,0);

            printf("%d\n",mmax[lrt]);

        }

    }



    return 0;

}

 

  

 

 

你可能感兴趣的:(play)