bzoj1208splay模板题

想试下新找的板子,没想到交上去CE了。。懒得调。。以后有机会就改

/*
用type标记当前树上的是宠物还是人
每次求前驱后缀,删掉最近的那个点
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define maxn 1000100
#define L ch[r][0]
#define R ch[r][1]
#define KT ch[ch[r][1]][0]

struct Splay{
    int pre[maxn],sz[maxn],ch[maxn][2],val[maxn],rt,tot;
    int flag;
    inline void newnode(int &r,int fa,int key){
        r=++tot;
        L=R=0;
        pre[r]=fa;
        val[r]=key;
        sz[r]=1;
        sz[L]=sz[R]=0;
    }   
    inline void pushup(int r){
        sz[r]=1;
        if(L) sz[r]+=sz[L];
        if(R) sz[r]+=sz[R];
    }
    inline void init(){//加两个边界
        rt=tot=flag=0;
        ch[rt][0]=ch[rt][1]=sz[rt]=pre[rt]=0;
        newnode(rt,0,-99999999);
        newnode(ch[rt][1],rt,9999999);
        memset(sz,0,sizeof sz);
    }
    inline void rotate(int x,int f) {
        int y=pre[x];
        ch[y][!f] = ch[x][f];
        pre[ ch[x][f] ] = y;
        pre[x] = pre[y];
        if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;
        ch[x][f] = y;
        pre[y] = x;
        pushup(y);
    }
    inline void splay(int x,int goal) { //将x旋转到goal的下面
        while(pre[x] != goal) {
            if(pre[pre[x]] == goal) rotate(x , ch[pre[x]][0] == x);
            else   {
                int y=pre[x],z=pre[y];
                int f = (ch[z][0]==y);
                if(ch[y][f] == x) rotate(x,!f),rotate(x,f);
                else rotate(y,f),rotate(x,f);
            }
        }
        pushup(x);
        if(goal==0) rt=x;
    }

    inline void insert(int &r,int key,int fa){
        if(!r){newnode(r,fa,key);splay(r,0);return;}
        else if(key<val[r]) insert(L,key,r);
        else insert(R,key,r);
        pushup(r);
    }
    inline int findkth(int r,int k){//找第k大的那个结点的值
        if(k==sz[L]+1) {splay(r,0);return val[r];}
        else if(k<sz[L]+1)
            return findkth(L,k);
        else return findkth(R,k-sz[L]-1);
    }
    inline int find(int r,int key){//找键值为key的结点
        if(!r) return 0;//不存在这个键值
        else if(key==val[r]) return r;
        else if(key<val[r]) find(L,key);
        else find(R,key);
    }
    void remove(){
        int t=rt;
        if(ch[rt][1]){//删掉根节点并以后缀作为根
            rt=ch[rt][1];
            splay(getmin(rt),0);
            ch[rt][0]=ch[t][0];
            if(ch[rt][0]) pre[ch[rt][0]]=rt;
        }
        else rt=ch[rt][0];
        pre[rt]=0;
        pushup(rt);
    }
    void findpre(int r,int key,int &ans){//找前驱结点(找值比key小的的最大的结点)
        if(!r) return;
        if(key>=val[r]) {ans=r;findpre(R,key,ans);}
        else findpre(L,key,ans);
    }
    void findsucc(int r,int key,int &ans){///找后继
        if(!r) return;
        if(key<=val[r]) {ans=r;findsucc(L,key,ans);}
        else findsucc(R,key,ans);
    }
    inline int getmin(int r){while(L) r=L;return r;}
    inline int getmax(int r){while(R) r=R;return r;}
    
    inline void vist(int r){
        if(r){
            printf("结点%2d : 左儿子  %2d   右儿子  %2d   val:%2d sz=%d\n",r,L,R,val[r],sz[r]);
            vist(L);
            vist(R);
        }
    }
    void debug() {
        puts("");
        vist(rt);
        puts("");
    }
}spt;
int main(){
    int n,a,b,ans;
    while(scanf("%d",&n)==1){
        spt.init();
        ans=0;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a,&b);
           // spt.debug();
            if(spt.sz[spt.rt]==2){
                spt.flag=a;
                spt.insert(spt.rt,b,0);
            }
            else {
                if(spt.flag==a) spt.insert(spt.rt,b,0);
                else {
                    int tmp1,tmp2;
                    spt.findpre(spt.rt,b,tmp1);
                    spt.findsucc(spt.rt,b,tmp2);
                    if(abs(b-spt.val[tmp1])<=abs(b-spt.val[tmp2])){
                        ans+=abs(b-spt.val[tmp1]);
                        spt.splay(tmp1,0);
                        spt.remove();
                    }
                    else {
                        ans+=abs(b-spt.val[tmp2]);
                        spt.splay(tmp2,0);
                        spt.remove();
                    }
                }
            }
           // spt.debug();
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted on 2018-11-22 20:05  zsben  阅读(210)  评论(0编辑  收藏  举报

导航