• Bzoj1588--Hnoi2002营业额统计


    平衡树练习

    每次插入一个数判断是否重复,重复则返回0,否则选出与它差最小的数返回差的绝对值

    最小差必定是左子树中最大点或右子树中最小点或其祖先,找找就可以了

    代码:

    #include<bits/stdc++.h>
    #define MAXN 300005
    #define MAXM 3005
    #define INF 10000000000000LL
    #define MOD 998244353
    #define LL long long
    using namespace std;
    
    inline int read() {
        int ret=0,f=1;char c=getchar();
        while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}
        while(c<='9'&&c>='0') {ret=ret*10+c-'0';c=getchar();}
        return ret*f;
    }
    
    inline LL _abs(LL a) {return a>0?a:-a;}
    
    int n;
    
    struct node{
        int son[2],par;LL v,r;
    }x[MAXN];
    struct Treap{
        int L,R,root,cnt;
        void init() {
            L=0;R=1;root=MAXN-5;cnt=0;
            x[MAXN-5].r=INF;x[MAXN-5].v=INF;
        }
        
        inline void rotate(int num,int p) {
            int pa=x[num].par;
            x[x[pa].par].son[x[x[pa].par].son[L]==pa?L:R]=num;
            x[pa].son[p^1]=x[num].son[p];if(x[num].son[p]) {x[x[num].son[p]].par=pa;}
            x[num].son[p]=pa;x[num].par=x[pa].par;x[pa].par=num;
        }
        
        int Insert(int v) {
            x[++cnt].v=v;x[cnt].r=rand()%MOD;
            int now=root,pre;LL le,ri;
            while(true) {
                if(v==x[now].v) {cnt--;return 0;}
                pre=v<x[now].v?L:R;
                if(!x[now].son[pre]) {x[now].son[pre]=cnt;x[cnt].par=now;break;}
                now=x[now].son[pre];
            }
            now=cnt;
            while(true) {
                if(x[x[now].par].son[L]==now) pre=R;else pre=L;
                if(x[now].r>x[x[now].par].r) rotate(now,pre);
                else break;
            }
            le=x[now].son[L];ri=x[now].son[R];
            while(x[le].son[R]) le=x[le].son[R];
            while(x[ri].son[L]) ri=x[ri].son[L];
            le=le?x[now].v-x[le].v:INF;ri=ri?x[ri].v-x[now].v:INF;
            now=x[now].par;
            if(le==ri&&le==INF&&now==root) return x[cnt].v;
            le=le<ri?le:ri;
            while(now) {
                le=le<_abs(x[now].v-x[cnt].v)?le:_abs(x[now].v-x[cnt].v);
                now=x[now].par;
            }
            return le;
        }
    };
    
    int main() {
        srand(2333333);
        n=read();LL ret=0;
        Treap p;p.init();
        for(int k,i=1;i<=n;i++) {
            k=read();
            ret+=p.Insert(k);
        }
        printf("%lld
    ",ret);
        return 0;
    }
  • 相关阅读:
    CKEditor 5 摸爬滚打(二)—— 自定义一个简单的加粗插件(上)
    由数组生成对称矩阵
    二终端网络可靠度
    多分类建模评估指标
    linux文本编辑器awk
    sklearn中的pipeline实际应用
    一觉醒来,我掉入计算机之中了···
    一个故事看懂计算机操作系统的进化史
    我是如何把计算机网络考了100分的?
    大一那会,我用QQ远程帮同学考过计算机二级
  • 原文地址:https://www.cnblogs.com/ihopenot/p/5915855.html
Copyright © 2020-2023  润新知