题目
有一个数据库,有两种操作:ADD(x),将数字x插入到数据库中;GET返回第i个元素,i初始为1,每次使用GET先将i增加1再查询。
分析
数据结构,首先利用离散化将数据映射到1~M,然后使用线段树进行存储和查找,记录每个区间的数据个数方便查询。
说明
注意数据中有M为0的情况,这时使用排序会RE。又是好久没刷题了(⊙o⊙)…。
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
//segment_tree__begin
typedef struct tnode
{
tnode* Lchild;
tnode* Rchild;
int Lvalue;
int Rvalue;
int Size;
int Value;
}tnode;
tnode Node[60006];
class segment_tree
{
private:
tnode* Root;
int Count;
tnode* madetree(int a, int b) {
tnode* np = &Node[Count ++];
np->Lvalue = a;
np->Rvalue = b;
np->Lchild = NULL;
np->Rchild = NULL;
np->Size = 0;
np->Value = 0;
if (a < b) {
np->Lchild = madetree(a, (a+b)/2);
np->Rchild = madetree((a+b)/2+1, b);
}
return np;
}
public:
segment_tree(int a, int b) {
Count = 0;
Root = madetree(a, b);
}
void Insert(int im, int re) {
Insert(Root, im, re);
}
int Query(int index) {
return Query(Root, index);
}
private:
void Insert(tnode* r, int im, int re) {
if (im == r->Lvalue && im == r->Rvalue) {
r->Value = re;
r->Size = 1;
} else {
r->Size ++;
if (r->Lchild && r->Lchild->Rvalue >= im) {
Insert(r->Lchild, im, re);
} else if (r->Rchild) {
Insert(r->Rchild, im, re);
}
}
}
int Query(tnode* r, int index) {
if (r->Lvalue == r->Rvalue && index == 1 && r->Size == 1) {
return r->Value;
} else {
if (r->Lchild && r->Lchild->Size >= index) {
return Query(r->Lchild, index);
} else if (r->Rchild) {
if (r->Lchild) {
return Query(r->Rchild, index - r->Lchild->Size);
} else if (r->Rchild->Size >= index) {
return Query(r->Rchild, index);
}
}
}
}
};
//segment_tree__end
int A[30003];
int u[30003];
int I[30003];
int S[30003];
bool my_cmp(int a, int b)
{
return A[a] < A[b];
}
int main()
{
int K, M, N;
while (~scanf("%d", &K))
while (K --) {
scanf("%d%d", &M, &N);
for (int i = 1; i <= M; ++ i) {
scanf("%d", &A[i]);
I[i] = i;
}
for (int i = 1; i <= N; ++ i) {
scanf("%d", &u[i]);
}
if (M) { // avoid M is 0
sort(I+1, I+M+1, my_cmp);
}
for (int i = 1; i <= M; ++ i) {
S[I[i]] = i;
}
segment_tree ST(1, M);
int index = 0, u_count = 1;
for (int i = 1; i <= M; ++ i) {
ST.Insert(S[i], A[i]);
while (u_count <= N && u[u_count] == i) {
// ST.output();
index ++;
printf("%d\n", ST.Query(index));
u_count ++;
}
}
if (K) {
puts("");
}
}
return 0;
}