码迷,mamicode.com
首页 > 其他好文 > 详细

无旋treap板子!

时间:2018-02-12 15:21:10      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:stream   pac   algorithm   const   span   return   mat   clu   names   

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
    if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
    x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x){
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}

const int N = 100005, INF = 0x3f3f3f3f;
typedef pair<int, int> par;
#define mp make_pair
int n, tot, root;
int ls[N], rs[N], data[N], key[N], sze[N];

void upt(int u){
    sze[u] = sze[ls[u]] + sze[rs[u]] + 1;
}
par split(int u, int k){
    if(!k) return mp(0, u);
    int l = ls[u], r = rs[u];
    if(k == sze[l]) return ls[u] = 0, upt(u), mp(l, u);
    if(k == sze[l] + 1) return rs[u] = 0, upt(u), mp(u, r);
    if(k < sze[l]){
    par tmp = split(l, k);
    return ls[u] = tmp.second, upt(u), mp(tmp.first, u);
    }
    par tmp = split(r, k - sze[ls[u]] - 1);
    return rs[u] = tmp.first, upt(u), mp(u, tmp.second);
}
int merge(int u, int v){
    if(u == 0 || v == 0) return u + v;
    if(key[u] < key[v]) return rs[u] = merge(rs[u], v), upt(u), u;
    else return ls[v] = merge(u, ls[v]), upt(v), v;
}
int getrank(int u, int x){
    int cnt = 0, ans = INF;
    while(u){
    if(x == data[u]) ans = min(ans, cnt + sze[ls[u]] + 1);
    if(x > data[u]) cnt += sze[ls[u]] + 1, u = rs[u];
    else u = ls[u];
    }
    return ans == INF ? cnt : ans;
}
int getkth(int u, int k){
    while(1){
    if(k == sze[ls[u]] + 1) return data[u];
    if(k <= sze[ls[u]]) u = ls[u];
    else k -= sze[ls[u]] + 1, u = rs[u]; //先修改k再移动u!我居然又写错了
    }
}
int getpre(int u, int x){
    int ans = -INF;
    while(u){
    if(data[u] < x) ans = max(ans, data[u]), u = rs[u];
    else u = ls[u];
    }
    return ans;
}
int getnxt(int u, int x){
    int ans = INF;
    while(u){
    if(data[u] > x) ans = min(ans, data[u]), u = ls[u];
    else u = rs[u];
    }
    return ans;
}
void insert(int x){
    data[++tot] = x, key[tot] = rand(), sze[tot] = 1;
    int k = getrank(root, x);
    par tmp = split(root, k);
    root = merge(tmp.first, tot);
    root = merge(root, tmp.second);
}
void erase(int x){
    int k = getrank(root, x);
    par tmp1 = split(root, k);
    par tmp2 = split(tmp1.first, k - 1);
    root = merge(tmp2.first, tmp1.second);
}

int main(){
    srand(20010424);
    read(n);
    int op, x;
    while(n--){
    read(op), read(x);
    if(op == 1) insert(x);
    else if(op == 2) erase(x);
    else if(op == 3) write(getrank(root, x)), enter;
    else if(op == 4) write(getkth(root, x)), enter;
    else if(op == 5) write(getpre(root, x)), enter;
    else write(getnxt(root, x)), enter;
    }
    return 0;
}

无旋treap板子!

标签:stream   pac   algorithm   const   span   return   mat   clu   names   

原文地址:https://www.cnblogs.com/RabbitHu/p/treap.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!