BZOJ 1588(营业额统计)

26 篇文章 1 订阅
19 篇文章 0 订阅

题意:每输入一个数,找出最接近它的一个数。

这题是比较裸的平衡树的题,可以用STL轻松解决,但是刚学了平衡树Treap,所以就练习下平衡树。

第一次写平衡树,代码从LRJ的白书上和网上拼拼凑凑写出来了,感觉还挺好,真是名不虚传,平衡树太强大了。

以前一直觉得平衡树有多难多复杂,多次尝试使劲学之后才发现,其实没有那么复杂-。-  代码封装得不够好,以后慢慢修改吧!

#include <cstdio>
#include <cmath>
#include <climits>
#include <time.h>
#include <algorithm>
using namespace std;
 
struct Node {
    Node *ch[2];
    int p, v;
    bool operator < (const Node rhs) const {
        return p < rhs.p;
    }
    
 	Node() {}
    Node(int _v) {
        ch[0] = ch[1] = NULL, p = rand(), v = _v;
    }
};

struct Treap {
	void rotate(Node* &o, int d) {
	    Node *z = o->ch[d ^ 1]; o->ch[d ^ 1] = z->ch[d];
	    z->ch[d] = o; o = z;
	}
 
	void insert(Node* &o, int x) {
	    if(o == NULL) {
	        o = new Node(x);
	    } else {
	        int d = x < o->v ? 0 : 1;
	        insert(o->ch[d], x);
	        if(o < o->ch[d])
	            rotate(o, d ^ 1);
	    }
	}
 
	void upper_bound(Node *o, int x, int &ans) {
	    if(o == NULL) return ;
	    if(o->v >= x) {
	        ans = o->v;
	        upper_bound(o->ch[0], x, ans);
	    } else {
	        upper_bound(o->ch[1], x, ans);
	    }
	}
 
	void lower_bound(Node *o, int x, int &ans) {
	    if(o == NULL) return ;
	    if(o->v <= x) {
	        ans = o->v;
	        lower_bound(o->ch[1], x, ans);
	    } else {
	        lower_bound(o->ch[0], x, ans);
	    }
	}
} tree;
 
int main() {
    int n, a, ans = 0, x, y;
    scanf("%d%d", &n, &a);
    Node *root = new Node(a);
    tree.insert(root, a), ans += a;
    for(int i = 1; i < n; i++) {
        if(scanf("%d",&a) == EOF)
            a = 0;
        tree.lower_bound(root, a, x);
        tree.upper_bound(root, a, y);
        ans += min(abs(a - x), abs(a - y));
        tree.insert(root, a);
    }
    printf("%d\n", ans);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值