Treap模板

其实之前一直认为Treap好难的,现在在网上看了几篇博文,这才发现Treap其实并没有什么难度。随机数可能有童鞋不会写,其实只要增加这些:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctime>
#include<cstring>

using namespace std;

int main() {
    srand(time(0));
    printf("%d\n", rand()%100);
    return 0;
}

这样就可以输出随机数了。
我喜欢写动态的Treap,于是就这样吧,然后就没有然后了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctime>
#include<cstring>

using namespace std;

#define REP(i, a, b) for(int i = (a), _end_ = (b);i <= _end_; ++i)

const int maxn = 30010;

struct treap{
    int val, pri, size;
    treap *l, *r;
    treap(int v) {
        l = NULL;
        r = NULL;
        val = v;
        pri = rand();
    }
} *tree;

int V[maxn];

int lsize(treap *p) {
    return p -> l ? p -> l -> size : 0;
}

int rsize(treap *p) {
    return p -> r ? p -> r -> size : 0; 
}

void lro(treap *&p) {
    treap *tmp = p -> r;
    p -> r = tmp -> l;
    tmp -> l = p;
    tmp -> size = p -> size;
    p -> size = lsize(p) + rsize(p) + 1;
    p = tmp;
}

void rro(treap *&p) {
    treap *tmp = p -> l;
    p -> l = tmp -> r;
    tmp -> r = p;
    tmp -> size = p -> size;
    p -> size = lsize(p) + rsize(p) + 1;
    p = tmp;
}

void insert(treap *&p, int val) {
    if(!p) {
        p = new treap(val);
        p -> size = 1;
    }
    else if(val <= p -> val) {
        p -> size++;
        insert(p -> l, val);
        if(p -> l -> pri < p -> pri)
            rro(p);
    }
    else if(val <= p -> val) {
        p -> size++;
        insert(p -> r, val);
        if(p -> r -> pri < p -> pri)
            lro(p);
    }
}

int find(int k, treap *p) {
    int tmp = lsize(p);
    if(k == tmp + 1)
        return p -> val;
    else if(k <= tmp)
        return find(k, p -> l);
    else
        return find(k - 1 - tmp, p -> r);
}

int main() {
    int n, m;
    int tmp = 1;
    tree = NULL;
    scanf("%d%d", &n, &m);
    REP(i, 1, n)
        scanf("%d", &V[i]);
    REP(i, 1, m) {
        int x;
        scanf("%d", &x);
        for(;tmp <= x; ++tmp)
            insert(tree, V[tmp]);
        printf("%d\n", find(i, tree));
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值