Splay模板(bzoj 1588)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define MAXN 100010
using namespace std;
struct STACK
{
    int tot,cnt;
    int A[MAXN];
    int Top()
    {
        if(!tot) return ++cnt;
        else return A[tot--];
    }
    void Push(int x)
    {
        A[++tot]=x;
    }
};
int sum,n,root,cnt,tmp;
struct Tree
{
    int fa,l,r;
    int val;
}t[100010];
void l_rotate(int x)
{
    int y=t[x].fa;int z=t[y].fa;
    t[y].l=t[x].r;
    if(t[x].r) t[t[x].r].fa=y;
    t[x].fa=z;
    t[x].r=y;
    if(z)
    {
        if(t[z].r==y) t[z].r=x;
        else t[z].l=x;
    }
    t[y].fa=x;
}
//x是y的左儿子 
void r_rotate(int x)
{
    int y=t[x].fa;int z=t[y].fa;
    t[y].r=t[x].l;
    if(t[x].l) t[t[x].l].fa=y;
    t[x].fa=z;
    t[x].l=y;
    if(z)
    {
        if(t[z].r==y) t[z].r=x;
        else t[z].l=x;
    }
    t[y].fa=x;
}
//x是y的右儿子 
void Splay(int x)
{
    if(x==root) return;
    while(t[x].fa!=root)
    {
        int y=t[x].fa;
        int z=t[y].fa;
        if(z==root)
        {
            if(t[y].l==x) l_rotate(x);
            else r_rotate(x);
            continue;
        }
        if(t[y].l==x)
        {
            if(t[z].l==y) {l_rotate(y);l_rotate(x);}
            else {l_rotate(x);r_rotate(x);}
        }
        else
        {
            if(t[z].l==y) {r_rotate(x);l_rotate(x);}
            else {r_rotate(y);r_rotate(x);}
        }
    }
}
int query_pre(int x)
{
    if(!t[x].l) 
    {
        int y=t[x].fa;
        if(t[y].r==x) return y;
        return -1;
    }
    x=t[x].l;
    while(t[x].r) x=t[x].r;
    return x; 
}
//查询前驱 
int query_sub(int x)
{
    if(!t[x].r) 
    {
        int y=t[x].fa;
        if(t[y].l==x) return y;
        return -1;
    }
    x=t[x].r;
    while(t[x].l) x=t[x].l;
    return x;
}
//查询后继 
void BST_insert(int p,int x)
{
    if(t[p].val==x){tmp=p;return;}
    if(t[p].val>x)
    {
        if(!t[p].l) {t[p].l=cnt;t[cnt].val=x;t[cnt].fa=p;}
        else BST_insert(t[p].l,x);
    }
    else 
    {
        if(!t[p].r) {t[p].r=cnt;t[cnt].val=x;t[cnt].fa=p;}
        else BST_insert(t[p].r,x);
    }
}
void insert(int x)
{
    tmp=++cnt;
    int minn=99999999;
    BST_insert(root,x);
    Splay(tmp);
    if(tmp!=cnt) return;
    int pre=query_pre(tmp);int sub=query_sub(tmp);
    if(pre!=-1) minn=min(minn,abs(x-t[pre].val));
    if(sub!=-1) minn=min(minn,abs(x-t[sub].val));
    sum+=minn;
}
int main()
{
    scanf("%d",&n);
    int aa;
    scanf("%d",&aa);
    t[++cnt].val=aa;
    sum+=aa;
    root=1;
    for(int i=2;i<=n;i++)
    {
        int a;
        scanf("%d",&a);
        insert(a);
    }
    printf("%d\n",sum);
}
bzoj 1588

往数列里插数,每次找到数列里和这个数相减绝对值最小的数,Splay棵题

posted @ 2017-11-03 16:27  秦こころ酱  阅读(115)  评论(0编辑  收藏  举报