[HNOI2002] 营业额统计

其实这个题不用平衡树也可以过的??(数据太水了啊)
但是我还是本着联系平衡树的想法打了一遍平衡树。
既然是最小的波动,那么直接找前驱后继就可以了呀qwq
代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,m,root,tot;
long long ans;
struct Node{int fa,val,ch[2],cnt;}t[MAXN<<2];
inline void rotate(int x)
{
    int y=t[x].fa;
    int z=t[y].fa;
    int k=t[y].ch[1]==x;
    t[z].ch[t[z].ch[1]==y]=x; t[x].fa=z;
    t[y].ch[k]=t[x].ch[k^1];  t[t[x].ch[k^1]].fa=y;
    t[x].ch[k^1]=y; t[y].fa=x;
}
inline void splay(int x,int goal)
{
    while(t[x].fa!=goal)
    {
        int y=t[x].fa;
        int z=t[y].fa;
        if(z!=goal) 
            ((t[y].ch[0]==x)^(t[z].ch[0]==y))?rotate(x):rotate(y);
        rotate(x);
    }
    if(!goal) root=x;
}
inline void find(int x)
{
    int u=root;
    if(!u) return;
    while(t[u].ch[t[u].val<x]&&x!=t[u].val)
        u=t[u].ch[t[u].val<x];
    splay(u,0);
}
inline int pre(int x,int f)
{
    find(x);
    int u=root;
    if((t[u].val<=x&&!f)||(t[u].val>=x&&f)) return u;
    u=t[u].ch[f];
    while(t[u].ch[f^1]) u=t[u].ch[f^1];
    return u;
}
inline void insert(int x)
{
    int u=root,ff=0;
    while(u&&t[u].val!=x)
        ff=u,u=t[u].ch[t[u].val<x];
    if(u) t[u].cnt++;
    else
    {
        u=++tot;
        if(ff) t[ff].ch[t[ff].val<x]=u;
        t[tot].fa=ff,t[tot].cnt=1,t[tot].val=x;
    }
    splay(u,0);
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    insert(-2147483627);insert(2147483627);
    scanf("%d",&ans);
    insert(ans);
    for(int i=2;i<=n;i++) 
    {
        int cur;
        scanf("%d",&cur);
        ans+=min(abs(t[pre(cur,0)].val-cur),abs(t[pre(cur,1)].val-cur));
        insert(cur);
    }
    printf("%lld
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/fengxunling/p/10281672.html