营业额统计

本文介绍了一种裸地平衡树的数据结构实现,并通过具体的代码示例详细解释了如何使用该结构来维护节点的前驱和后继。文章还展示了如何进行插入操作以及查找指定节点的前驱与后继。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

裸地平衡树,维护前驱后继。

// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
using namespace std;
int abs(int x){return x>0?x:-x;}
int n,root=0,tot=0,ans,inf=0x7ffffff;
struct Splaytree{
    int ch[110000][3];
    int key[110000], size[190099],cnt[110000],f[110000];
    inline void clear(int x){
        key[x]=size[x]=cnt[x]=f[x]=ch[x][0]=ch[x][1]=0;
    }
    inline void update(int x){
        if(x){
            size[x]=cnt[x];
            if(ch[x][0])
            size[x]+=size[ch[x][0]];
            if(ch[x][1])
            size[x]+=size[ch[x][1]];
        }       
    }
    inline int get(int x){
        return ch[f[x]][1]==x;
    }
    inline void retoto(int x){
        int old=f[x],old2=f[f[x]],opt=get(x),opt2=get(f[x]);
        ch[old][opt]=ch[x][opt^1];f[ch[x][opt^1]]=old;
        f[old]=x;ch[x][opt^1]=old;
        f[x]=old2;
        if(old2)ch[old2][opt2]=x;
        update(old);update(x);
    }
    inline void splay(int x){
        for(int i;i=f[x];retoto(x)) if(f[i]) {
            retoto((get(x)==get(i))?i:x);
        }
        root=x;
    }
    inline void insert(int x){
        int tmp=root,fa=0;
        if(!root){f[++tot]=ch[tot][1]=ch[tot][0]=0,key[tot]=x,size[tot]=cnt[tot]=1,root=tot;return;}
        while(1){
            if(key[tmp]==x) {
                cnt[tmp]++,update(tmp),update(fa);splay(tmp);return ;
            }
            fa=tmp;
            tmp=ch[tmp][key[tmp]<x];
            if(!tmp){
                f[++tot]=fa,ch[fa][key[fa]<x]=tot,key[tot]=x,size[tot]=cnt[tot]=1;
                update(fa);
                splay(tot);return;
            }
        }
    }

    inline int pre(){
        if(cnt[root]>1) return key[root];
        int tmp=ch[root][0];if(!tmp)return inf;
        while(ch[tmp][1]) tmp=ch[tmp][1];
        return key[tmp];
    }
    inline int next(){
        if(cnt[root]>1) return key[root];
        int tmp=ch[root][1];if(!tmp) return -inf;
        while(ch[tmp][0]) tmp=ch[tmp][0];
        return key[tmp];
    }
}s;
int main(){
    scanf("%d",&n);//s.insert(-inf),s.insert(inf);
    for(int i=1,x;i<=n;i++){
        scanf("%d",&x);
        s.insert(x);
        ans+=(i==1)?x:min(abs(x-s.pre()),abs(s.next()-x));
    }
    printf("%d",ans); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值