tyvj 1185 营业额统计 splay入门

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 maxn=1000100;
const int INF=1e9+10;

struct Splay
{
    int key[maxn];
    int pre[maxn];
    int ch[maxn][2];
    int rt,tot;
    void newnode(int &r,int fa,int k)
    {
        r=++tot;
        key[r]=k;
        pre[r]=fa;
        ch[r][0]=ch[r][1]=0;
    }
    void rot(int x,int op)
    {
        int y=pre[x];
        ch[y][op^1]=ch[x][op];
        pre[ch[x][op]]=y;
        if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];
        ch[x][op]=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];
                int op=ch[pre[y]][0]==y;
                if(ch[y][op]==x) rot(x,op^1),rot(x,op);
                else rot(y,op),rot(x,op);
            }
        }
        if(goal==0) rt=x;
    }
    int insert(int k)
    {
        int u=rt;
        while(ch[u][k>key[u]]){
            if(k==key[u]){
                splay(u,0);
                return 0;
            }
            u=ch[u][k>key[u]];
        }
        newnode(ch[u][k>key[u]],u,k);
        splay(ch[u][k>key[u]],0);
        return 1;
    }
    void init()
    {
        MS0(pre);
        tot=0;
        newnode(rt,0,-INF);
        insert(INF);
    }
    int get_pre(int x)
    {
        int u=ch[x][0];
        while(ch[u][1]) u=ch[u][1];
        return key[u];
    }
    int get_next(int x)
    {
        int u=ch[x][1];
        while(ch[u][0]) u=ch[u][0];
        return key[u];
    }
};Splay tree;
int n,a[maxn];

int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>n){
        tree.init();
        int ans=0;
        REP(i,1,n){
            scanf("%d",&a[i]);
            if(!tree.insert(a[i])) continue;
            int tmp=0;
            if(i==1) tmp=a[i];
            else{
                int x=tree.get_pre(tree.rt);
                int y=tree.get_next(tree.rt);
                tmp=min(abs(x-a[i]),abs(y-a[i]));
                //cout<<x<<" "<<y<<" "<<a[i]<<endl;
            }
            ans+=tmp;
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

 

以上是关于tyvj 1185 营业额统计 splay入门的主要内容,如果未能解决你的问题,请参考以下文章

[平衡树-Splay]营业额统计

bzoj1588: [HNOI2002]营业额统计 splay瞎写

BZOJ-1588营业额统计 Splay

BZOJ1588 [HNOI2002]营业额统计 splay模板

BZOJ 1588:营业额统计(Splay)

题解 [HNOI2002]营业额统计 (Splay)