tyvj 1185 营业额统计 splay入门

第一道splay,算是学会了最最基础的splay操作。

有一点要特别注意,就是一字型旋转的时候要先旋转y再旋x,这样复杂度降低很多。。。不要写成两次都旋转x。。。

总算是调试好了。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int INF=1e9+10;
const int maxn=1000100;

int key[maxn],pre[maxn];
int ch[maxn][2];
int rt,tot;
int n,x;

void newnode(int &r,int fa,int k)
{
    r=++tot;
    pre[r]=fa;key[r]=k;
    MS0(ch[r]);
}

void rot(int x,int kind)
{
    int y=pre[x];
    ch[y][kind^1]=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;
}

void splay(int x,int goal)
{
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal) rot(x,ch[pre[x]][0]==x);
        else{
            int y=pre[x],z=pre[y];
            int kind=ch[y][0]==x,one=0;
            if(ch[y][0]==x&&ch[z][0]==y) one=1;
            if(ch[y][1]==x&&ch[z][1]==y) one=1;
            if(one) rot(y,kind),rot(x,kind);
            else rot(x,kind),rot(x,kind^1);
        }
    }
    if(goal==0) rt=x;
}

int Insert(int x)
{
    int u=rt,f=0;
    while(u){
        if(key[u]==x){
            splay(u,0);
            return 0;
        }
        f=u;
        u=ch[u][x>key[u]];
    }
    newnode(ch[f][x>key[f]],f,x);
    splay(ch[f][x>key[f]],0);
    return 1;
}

int get_pre(int x)
{
    if(!ch[x][0]) return -INF;
    x=ch[x][0];
    while(ch[x][1]) x=ch[x][1];
    return key[x];
}

int get_next(int x)
{
    if(!ch[x][1]) return INF;
    x=ch[x][1];
    while(ch[x][0]) x=ch[x][0];
    return key[x];
}

void get(int u)
{
    if(u==0) return;
    if(ch[u][0]) get(ch[u][0]);
    printf("u=%2d key=%2d lch=%2d rch=%2d fa=%2d\n",u,key[u],ch[u][0],ch[u][1],pre[u]);
    if(ch[u][1]) get(ch[u][1]);
}

int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>n){
        rt=tot=0;MS0(pre);MS0(ch);
        int ans=0;
        REP(i,1,n){
            scanf("%d",&x);
            if(i==1){
                ans+=x;
                newnode(rt,0,x);
                continue;
            }
            if(!Insert(x)) continue;
            int a=get_pre(rt),b=get_next(rt);
            //get(rt);
            ans+=min(abs(a-x),abs(b-x));
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

 

posted @ 2016-02-18 11:18  __560  阅读(277)  评论(0编辑  收藏  举报