【序列操作V】平衡树(无旋treap)

题目描述

维护一个队列,初始为空。依次加入 n(1≤n≤105)个数 ai(-109≤ai≤109),第 i(1≤i≤n)个数加入到当前序列第 bi(0≤bi≤当前序列长度)个数后面。输出最终队列。

输入格式

输入包含一个数 n(1≤n≤3×105),表示最终序列长度。

接下来 n 行,每行两个数 ai,bi,表示把 ai 放在当前序列第 bi 个数后面。

输出格式

输出 n 行,每行一个数,表示最终序列。

样例数据 1

输入


1 0 
2 0 
3 0 
4 0 
5 0

输出





1

题目分析

  平衡树如splay/treap应该都能完成,这里给出无旋treap的做法。用无旋treap的话简直就是裸题,时间复杂度nlogn

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;

const int N = 3e5 + 5;
int n;
#define SZ(x) (x?x->sze:0)
inline void wr(int);
struct node{
    node *lc, *rc;
    int pri, sze, val;
    inline node* upt(){
        sze = SZ(lc) + SZ(rc) + 1;
        return this;
    }
    inline void print(){
        if(lc) lc->print();
        wr(val), putchar('\n');
        if(rc) rc->print();
    }
}pool[N], *tail = pool, *root = NULL;

inline int read(){
    int i = 0, f = 1; char ch = getchar();
    for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
    if(ch == '-') f = -1, ch = getchar();
    for(; ch >= '0' && ch <= '9'; ch = getchar())
        i = (i << 3) + (i << 1) + (ch - '0');
    return i * f;
}

inline void wr(int x){
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) wr(x / 10);
    putchar(x % 10 + '0');
}

inline int Rand(){
    static int RAND_VAL = 1388593021;
    return RAND_VAL += RAND_VAL << 2 | 1;
}

inline node* newNode(int v){
    node *x = tail++;
    x->lc = x->rc = NULL;
    x->pri = Rand();
    x->val = v;
    x->sze = 1;
    return x;
}

inline node* Merge(node *u, node *v){
    if(!u) return v->upt();
    if(!v) return u->upt();
    if(u->pri < v->pri){
        u->rc = Merge(u->rc, v);
        return u->upt();
    }
    else{
        v->lc = Merge(u, v->lc);
        return v->upt();
    }
}

inline void Split_k(node *u, int k, node *&x, node *&y){
    if(!u){
        x = y = NULL;
        return;
    }
    if(SZ(u->lc) < k){
        Split_k(u->rc, k - SZ(u->lc) - 1, x, y);
        u->rc = NULL, u->upt();
        x = Merge(u, x);
    }
    else{
        Split_k(u->lc, k, x, y);
        u->lc = NULL, u->upt();
        y = Merge(y, u);
    }
}

inline node* Insert(node *u, int k, int v){
    node *L, *R;
    Split_k(u, k, L, R);
    node *res = newNode(v);
    return Merge(Merge(L, res), R);
}

int main(){
    n = read();
    for(int i = 1; i <= n; i++){
        int a = read(), b = read();
        root = Insert(root, b, a);
    }
    root->print();
    return 0;
}
posted @ 2017-07-27 20:04  CzYoL  阅读(236)  评论(0编辑  收藏  举报