题目描述
在 J 班的体育课上, 同学们常常会迟到几分钟, 但体育老师的点名却一直很准时.
老师只关心同学的身高, 他会依次询问当前最高的身高, 次高的身高, 第三高的身高, 等等. 在询问的过程中, 会不时地有人插进队伍里. 你需要回答老师每次的询问.
输入格式
第一行两个整数 \(n\)\(m\), 表示先后有 \(n\) 个人进队, 老师询问了 \(m\) 次
第二行 \(n\) 个整数, 第 \(i\) 个数 \(A_i\) 表示第 \(i\) 个进入队伍的同学的身高为 \(A_i\)
第三行 \(m\) 个整数, 第 \(j\) 个数 \(B_j\) 表示老师在第 \(B_j\) 个同学进入队伍后有一次询问
输出格式
\(m\) 行, 每行一个整数, 依次表示老师每次询问的答案. 数据保证合法.
样例输入
7 4
9 7 2 8 14 1 8
1 2 6 6
样例输出
9
9
7
8
样例解释
(9) {No. 1=9}; (9 7) {No. 2=9}; (9 7 2 8 14 1) {No. 3=7; No. 4=8}
数据范围
40% 的数据保证 \(n \leq 1000\)
100% 的数据保证 \(1 \leq m \leq n \leq 30000\);\(0 \leq A_i \lt 2^{32}\)
Explanation
暴力可以水 40 分.
如果要 100 分做法需要用 Treap 或 Splay 维护第 K 大值.
但是 Splay 调不出来啊~
所以就用了 @xmcp 的代码.
Source Code
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long lli;
const int maxn = 40010;
const lli infinit = 0x007f7f7f7f7f7f7fll;
/*
class SplayTree
{
public:
int parent[maxn], ch[maxn][2], root, ncnt, n;
int size[maxn];
lli val[maxn];
#define lc(_x) ch[_x][0]
#define rc(_x) ch[_x][1]
#define par(_x) parent[_x]
int makenode(int q, lli v) {
int p = ++ncnt; n++;
lc(p) = rc(p) = 0;
par(p) = q;
size[p] = 1;
val[p] = v;
return p; }
void rotate(int p) {
int q = par(p), g = par(q), x = p == rc(q);
// Relink connections
ch[q][x] = ch[p][!x]; if (ch[q][x]) par(ch[q][x]) = q;
ch[p][!x] = q, par(q) = p;
par(p) = g; if (g) ch[g][rc(g) == q] = p;
size[q] = size[lc(q)] + 1 + size[rc(q)];
size[p] = size[lc(p)] + 1 + size[rc(p)];
return ; }
void splay(int p, int t) {
for (int q = 0; (q = par(p)) && q != t; rotate(p))
if (par(q) && par(q) != t)
rotate((p == lc(q)) == (q == lc(par(q))) ? q : p);
if (t == 0) root = p; }
int pre(int p) {
cout << "preing " << p << endl;
if (!lc(p)) { while (p == lc(par(p))) p = par(p); p = par(p); }
if { p = lc(p); while (rc(p)) p = rc(p); }
return p; }
int find(int x) {
int p = root;
while (true) {
if (size[lc(p)] >= x) {
p = lc(p); continue;
} x -= size[lc(p)];
if (x == 1) return p; x -= 1;
p = rc(p);
} return root; }
int locate(lli v) {
int p = root;
while (true) {
if (v > val[p] && rc(p)) {
p = rc(p); continue; }
if (v == val[p]) return p;
if (lc(p)) p = lc(p); else return p;
} return root; }
lli query(int x) {
int m = n - 1 - x;
return val[find(m + 1)]; }
void dfs(int p)
{
if (!p) return ;
printf("%d %d %d\n", par(p), p, p==rc(par(p)));
dfs(lc(p));
dfs(rc(p));
}
void dfstree(void)
{
dfs(root);
}
void insert(lli v) {
int rp = locate(v), lp = pre(lp);
cout << rp << ' ' << lp << "*\n";
splay(rp, 0);
splay(lp, root);
int c = makenode(lp, v);
rc(lp) = c;
size[lp]++, size[rp]++;
dfstree();
return ; }
void build_tree(void) {
n = ncnt = 0;
root = makenode(0, 0);
rc(root) = makenode(root, infinit);
par(rc(root)) = root;
size[root]++; }
} st; */
#define $ if(0)
class XmcpsSplayTree
{
public:
static const int _N=50007, _I=2147000000;
int child[_N][2], parent[_N], size[_N];
lli value[_N];
int root, graphtop;
int query[_N];
int insvalue[_N];
bool inserted;
void build_tree(void) {
root = 1, graphtop = 2;
inserted = false;
}
int flag(int x) {
return x[parent][child][1]==x;
}
void rotate(int self) {
int flaj=flag(self),
p=self[parent],
pp=p[parent],
ch=self[child][!flaj];
/****/ self[parent]=pp;
if(pp) pp[child][flag(p)]=self;
/****/ p[parent]=self;
/****/ self[child][!flaj]=p;
if(ch) ch[parent]=p;
/****/ p[child][flaj]=ch;
p[size]=p[child][0][size]+p[child][1][size]+1;
}
void splay(int self) {
int p,pp;
while((p=self[parent])) {
if((pp=p[parent]))
rotate(flag(self)==flag(pp)?p:self);
rotate(self);
}
root=self;
}
void insert__(lli val) {
while(true) {
int ch=root[child][root[value]<val];
if(!ch) {
ch=graphtop++;
ch[value]=val;
ch[child][0]=ch[child][1]=0;
ch[parent]=root;
ch[size]=1;
root[child][root[value]<val]=ch;
splay(ch);
return;
}
root=ch;
}
}
void insert(lli val) {
if (!inserted) {
root[value] = val;
inserted = true;
return ;
}
insert__(val);
}
lli queryf(int k)
{
// int target = root;
$ printf("get %d\n",k);
int self=root,szl;
while((szl=self[child][0][size])!=k-1) {
if(szl>k-1) {
$ puts("goto left");
self=self[child][0];
}
else {
$ puts("goto right");
self=self[child][1],
k-=szl+1;
}
$ printf("now size of left = %d\n",szl);
}
$ printf("value is %lld\n",self[value]);
return self[value];
}
} st;
int n, m;
lli ins[maxn];
vector<int> qry[maxn];
int main(int argc, char** argv)
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%lld", &ins[i]);
for (int i = 1, a; i <= m; i++) {
scanf("%d", &a);
qry[a].push_back(i);
}
// Querying while inserting
st.build_tree();
for (int i = 1; i <= n; i++) {
st.insert(ins[i]);
for (unsigned int j = 0; j < qry[i].size(); j++)
printf("%lld\n", st.queryf(qry[i][j]));
}
return 0;
}