• 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
    " :: "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
    ",val[x]);
            dfs(b);
        }
    }
    
    void gdb(){
        puts("
    ---------------------");
        dfs(root);
        puts("---------------------
    ");
    }
    
    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
    ",mmax[lrt]);
            }
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    java如何手动创建一个线程池
    HashMap的面试总结(摘抄)
    JDK源码调试
    分布式和集群的区别
    开发中model,entity和pojo的区别
    java并发编程_CountDownLanch(倒计数锁存器)应用场景
    Map 怎么排序
    java中Thread的 interrupt异常处理
    zookeeper节点失效重连机制
    java并发库_并发库知识点整理
  • 原文地址:https://www.cnblogs.com/yejinru/p/3286482.html
Copyright © 2020-2023  润新知