zoukankan      html  css  js  c++  java
  • HNOI2002

     对于当天的营业额,你要找到之前的数和他差的绝对值最小的和。由于这个是不断在插入的,所以用伸展树来维护。

    http://www.lydsy.com/JudgeOnline/problem.php?id=1588

    照着kuangbin大牛的代码敲下来的。

    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define INF 99999999
    #define ll __int64
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int MAXN = 100005;
    int pre[MAXN],key[MAXN],ch[MAXN][2],root,tot;
    //父亲结点 键值 左右子树 根节点 节点数量
    int n;
    void Newnode(int &rt,int pa,int k)
    {
        rt = ++tot;
        pre[rt] = pa;
        key[rt] = k;
        ch[rt][0] = ch[rt][1] = 0;//
    }
    
    void Rotate(int x,int kind)
    {
        int y = pre[x];
        ch[y][!kind] = ch[x][kind];
        pre[ch[x][kind]] = y;
        if(pre[y]){
            ch[pre[y]][ch[pre[y]][1]==y] = x;
        }
        pre[x] = pre[y];
        ch[x][kind] = y;
        pre[y] = x;
    }
    
    //将结点rt 调整到goal下面
    void splay(int rt,int goal)
    {
        while(pre[rt] != goal)
        {
            if(pre[pre[rt]] == goal)
                Rotate(rt,ch[pre[rt]][0]==rt);
            else {
                int y = pre[rt];
                int kind = (ch[pre[y]][0]==y);
                if(ch[y][kind] == rt){//rt 和 pre[rt]不在同一方向上
                    Rotate(rt,!kind); //kind=1时,说明rt在y的右边 而y在pre[y]的左边
                    Rotate(rt,kind);
                }
                else {
                    Rotate(y,kind);
                    Rotate(rt,kind);
                }
            }
        }
        if(goal == 0)
            root = rt;
    }
    
    int Insert(int k)
    {
        int rt = root;
        while(ch[rt][key[rt]<k]){//如果key[r]<k,表明当前k在右边,不然去左边
            if(key[rt] == k){
                splay(rt,0);
                return 0;
            }
            rt = ch[rt][key[rt]<k];
        }
        Newnode(ch[rt][key[rt]<k],rt,k);
        splay(ch[rt][key[rt]<k],0);
        return 1;
    }
    
    int get_pre(int rt)
    {
        int tmp = ch[rt][0];
        if(tmp == 0)
            return INF;
        while(ch[tmp][1])
        {
            tmp = ch[tmp][1];
        }
        return key[rt] - key[tmp];
    }
    
    int get_next(int rt)
    {
        int tmp = ch[rt][1];
        if(tmp == 0)
            return INF;
        while(ch[tmp][0])
        {
            tmp = ch[tmp][0];
        }
        return key[tmp] - key[rt];
    }
    int main()
    {
        int i,j;
        while(~scanf("%d",&n))
        {
            root = tot = 0;
            int ans = 0;
            for(i=1; i<=n; i++){
                int num;
                if(scanf("%d",&num)==EOF)num = 0;
                if(i == 1){
                    ans += num;
                    Newnode(root,0,num);
                    continue;
                }
                if(Insert(num) == 0)
                    continue;
                int a = get_pre(root);
                int b = get_next(root);
                //cout<<a<<" "<<b<<endl;
                ans += min(a,b);
            }
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    回调函数 协程
    网络编程 之线程
    并发编程 之进程相关
    并发编程的理论 python中实现多进程
    基于tcp的粘包处理终极版本
    基于socket的网络编程
    数据分析
    zabbix从入门到放弃
    Linux
    Django
  • 原文地址:https://www.cnblogs.com/sweat123/p/5135018.html
Copyright © 2011-2022 走看看