其实之前一直认为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;
}