[Treap] poj 1442 Black Box

来源:互联网 发布:喜剧片 知乎 编辑:程序博客网 时间:2024/06/07 10:52

题意

给出一个队列, 然后对于u(i),查询从第一个到u(i)的这一串当中的第i个数

思路

基本就是Treap的裸题,然后静态处理,因为u(i)是有序的,所以可以按照顺序来查询,然后基本就是套Treap的模板了

代码

依旧是谜一般的RE,去掉了srand就AC了……至今都不知道是为什么

#include <ctime>#include <cstdio>#include <cstdlib>#include <algorithm>using namespace std;struct Treap {    struct Node {        Node *ch[2];        int r;        int v;        int s;        int cmp(int x) const {            if(x == v) return -1;            return x < v ? 0 : 1;        }        void maintain() {            s = 1;            if(ch[0] != NULL) {                s += ch[0] -> s;            }            if(ch[1] != NULL) {                s += ch[1] -> s;            }        }    } *root;    void init() {        root = NULL;//      srand(time(0));    }    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 = new Node();            o -> ch[0] = o -> ch[1] = NULL;            o -> v = x;            o -> r = rand();        } else {            int d = (x  v ? 0 : 1);            insert(o -> ch[d], x);            if(o -> ch[d] -> r > o -> r) {                rotate(o, d ^ 1);            }        }        o -> maintain();    }    void remove(Node* &o, int x) {        int d = o -> cmp(x);        if(d == -1) {            Node* u = o;            if(o -> ch[0] != NULL && o -> ch[1] != NULL) {                int d2 = (o -> ch[0] -> r > o -> ch[1] -> r ? 1 : 0);                rotate(o, d2);                remove(o -> ch[d2], x);            } else {                if(o -> ch[0] == NULL) {                    o = o -> ch[1];                } else {                    o = o -> ch[0];                }                delete u;            }        } else {            remove(o -> ch[d], x);        }        if(o != NULL) {            o -> maintain();        }    }    int find(Node* o, int x) {        while(o != NULL) {            int d = o -> cmp(x);            if(d == -1) return 1;             else o = o -> ch[d];        }        return 0;    }    int kth(Node* o, int k) {        if(o == NULL || k > o -> s || k <= 0) {            return -1;        }        int s = (o -> ch[0] == NULL ? 0 : o -> ch[0] -> s);        if(k == s + 1) {            return o -> v;        } else {            if(k <= s) {                return kth(o -> ch[0], k);            } else {                return kth(o -> ch[1], k - s - 1);            }        }    }} treap;const int MAXN = 100010;int a[MAXN];int main(void) {    treap.init();    int n, m;    scanf("%d%d", &n, &m);    for(int i = 0; i < n; ++i) {        scanf("%d", &a[i]);    }    int r = 0;    for(int i = 1; i <= m; ++i) {        int x;        scanf("%d", &x);        for(; r < x; ++r) {            treap.insert(treap.root, a[r]);        }        printf("%d\n", treap.kth(treap.root, i));    }    return 0;}