题意
给出一个队列, 然后对于 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;
}