HDU 4585 Shaolin 找最接近的数 Treap / set

6 篇文章 0 订阅

题目链接

题意

若干组插入与询问,每次询问与当前要插入的数最接近的数。

思路

向左走向右走的时候记录一下即可。

(是最近写的 Treap 里面最简单的了(躺倒

写博客的时候想了一下,为啥不用 set 呢!因为是搜 HDU 上 Treap 相关的题目搜到的这题...。
用 set 几行就搞定了吗= =而且写 Treap 就相当于自己写了个 set 啊…。
(写 set 一开始一直 t ,后来才知道 lower_bounds.lower_bound(x) 而不是 lower_bound(s.begin(), s.end(), x)

Code

Treap

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
map<int, int> m;
struct node {
    node* ch[2];
    int val, key, sz;
    node() { sz = 0; key = INT_MAX; }
    node(int x);
    void update() { sz = ch[0]->sz + ch[1]->sz + 1; }
}* null = new node;
node::node(int x) { sz = 1, val = x, key = rand(); ch[0] = ch[1] = null; }
struct Treap {
    node* root;
    Treap() { root = null; }
    bool empty() { return root == null; }
    void rotate(node*& t, bool d) {
        node* p = t->ch[d];
        t->ch[d] = p->ch[!d];
        p->ch[!d] = t;
        t->update(), p->update();
        t = p;
    }
    void insert(node*& t, int x, int& lo, int& hi) {
        if (t == null) { t = new node(x); return; }
        bool d = x > t->val;
        if (d == 0) hi = t->val;
        else lo = t->val;
        insert(t->ch[d], x, lo, hi);
        if (t->ch[d]->key < t->key) rotate(t, d);
        else t->update();
    }
    int findpos(int x) {
        int lo = -inf, hi = inf;
        insert(root, x, lo, hi);
        return hi-x < x-lo ? hi : lo;
    }
    void clear(node*& t) {
        if (t->ch[0] != null) clear(t->ch[0]);
        if (t->ch[1] != null) clear(t->ch[1]);
        delete t; t = null;
    }
    void clear() { clear(root); }
    void insert(int x) { int lo, hi; insert(root, x, lo, hi); }
}* treap = new Treap;
int n, id, x;
void work() {
    if (!treap->empty()) treap->clear();
    treap->insert(1000000000);
    m.clear(); m[1000000000] = 1;
    for (int i = 0; i < n; ++i) {
        scanf("%d%d", &id, &x);
        m[x] = id;
        printf("%d %d\n", id, m[treap->findpos(x)]);
    }
}
int main() {
    while (scanf("%d", &n) && n) work();
    return 0;
}

Set

#include <bits/stdc++.h>
using namespace std;
map<int, int> m;
set<int> s;
int n, id, x;
void work() {
    s.clear(); s.insert(1000000000);
    m.clear(); m[1000000000] = 1;
    for (int i = 0; i < n; ++i) {
        scanf("%d%d", &id, &x);
        auto it = s.lower_bound(x);
        int g;
        if (it == s.begin()) g = *it;
        else if (it == s.end()) g = *(--it);
        else {
            int hi = *it; int lo = *(--it);
            g = hi - x < x - lo ? hi : lo;
        }
        printf("%d %d\n", id, m[g]);
        m[x] = id;
        s.insert(x);
    }
}
int main() {
    while (scanf("%d", &n) != EOF && n) work();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值