BZOJ1588——[HNOI2002]营业额统计

1、题目大意:一个简单的treap模板题(我才不告诉你题目少一句话呢,看discuss去

2、分析:treap模板题

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node{
    Node *ch[2];
    int v, r, num, s;
    bool operator < (const Node& rhs) const{
        return r < rhs.r;
    } 
    int cmp(int x){
        if(x == v) return -1;
        if(x < v) return 0;
        return 1;
    }
    void maintain(){
        s = num;
        if(ch[0]) s += ch[0] -> s;
        if(ch[1]) s += ch[1] -> s;
    }
};
struct treap{
    Node ft[1000000], *root;
    int cnt;
    void rotate(Node* &o, int d){
        Node *k = o -> ch[d ^ 1];
        o -> ch[d ^ 1] = k -> ch[d];
        k -> ch[d] = o;
        o -> maintain();
        k -> maintain();
        o = k;
    }
    void insert(Node* &o, int x){
        if(o == NULL){
            o = &ft[cnt ++];
            o -> r = rand();
            o -> num = o -> s = 1;
            o -> v = x;
            o -> ch[0] = o -> ch[1] = 0;
        }
        else {
            int d = o -> cmp(x);
            if(d == -1){
                o -> num ++;
            }
            else {
                insert(o -> ch[d], x);
                if(o -> ch[d] > o) rotate(o, d ^ 1);
            }
        }
        o -> maintain();
    }
    int kth(Node* &o, int k){
        int st = o -> num;
        if(o -> ch[0]) st += o -> ch[0] -> s;
        if(st - o -> num + 1 <= k && k <= st){
            return o -> v;
        } 
        if(st - o -> num + 1 > k){
            return kth(o -> ch[0], k);
        }
        else{
            return kth(o -> ch[1], k - st);
        }
    }
    int less_k(Node* &o, int k){
        if(o == NULL) return 0;
        int d = o -> cmp(k);
        int st = o -> num;
        if(o -> ch[0]) st += o -> ch[0] -> s;
        if(d == -1) return st - o -> num;
        if(d == 0) return less_k(o -> ch[0], k);
        else return less_k(o -> ch[1], k) + st;
    } 
} wt;
int a[1000000];
int main(){
    int n;
    scanf("%d", &n);
    int tt = 0;
    while(scanf("%d", &a[++ tt]) != EOF);
    int ans = 0;
    wt.insert(wt.root, a[1]);
    for(int i = 2; i <= n; i ++){
        int hh = wt.less_k(wt.root, a[i]);
        int oo = 2147483647;
        if(hh) oo = min(oo, abs(wt.kth(wt.root, hh) - a[i]));
        if(hh + 1 <= wt.root -> s) oo = min(oo, abs(wt.kth(wt.root, hh + 1) - a[i]));
        wt.insert(wt.root, a[i]);
        ans += oo;
    } 
    printf("%d\n", ans + a[1]);
    return 0;
}


你可能感兴趣的:(treap,1588,bzoj,HNOI2002,营业额统计)