[LUOGU] P1801 黑匣子_NOI導刊2010提高(06)
阿新 • • 發佈:2019-02-15
Black Box是一種原始的資料庫。它可以儲存一個整數陣列,還有一個特別的變數i。最開始的時候Black Box是空的.而i等於0。這個Black Box要處理一串命令。
命令只有兩種:
ADD(x):把x元素放進BlackBox;
GET:i加1,然後輸出Blackhox中第i小的數。
記住:第i小的數,就是Black Box裡的數的按從小到大的順序排序後的第i個元素。例如:
我們來演示一下一個有11個命令的命令串。(如下圖所示)
(我是圖)
現在要求找出對於給定的命令串的最好的處理方法。ADD和GET命令分別最多200000個。現在用兩個整數陣列來表示命令串:
1.A(1),A(2),…A(M):一串將要被放進Black Box的元素。每個數都是絕對值不超過2000000000的整數,M$200000。例如上面的例子就是A=(3,1,一4,2,8,-1000,2)。
2.u(1),u(2),…u(N):表示第u(j)個元素被放進了Black Box裡後就出現一個GET命令。例如上面的例子中u=(l,2,6,6)。輸入資料不用判錯。
輸入輸出格式
輸入格式:
第一行,兩個整數,M,N。
第二行,M個整數,表示A(l)
……A(M)。
第三行,N個整數,表示u(l)
…u(N)。
輸出格式:
輸出Black Box根據命令串所得出的輸出串,一個數字一行。
輸入輸出樣例
輸入樣例#1:
7 4
3 1 -4 2 8 -1000 2
1 2 6 6
輸出樣例#1:
3
3
1
2
說明
對於30%的資料,M≤10000;
對於50%的資料,M≤100000:
對於100%的資料,M≤200000。
殘缺的平衡樹,區域性變數!!
#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN=200005;
inline int rd() {
int ret=0,f=1;
char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10 +c-'0',c=getchar();
return ret*f;
}
int n,m;
int que[MAXN],data[MAXN];
int val[MAXN],siz[MAXN],cnt[MAXN];
int ch[MAXN][2],fa[MAXN];
int root,tot;
inline bool check(int x) {
return x==ch[fa[x]][1];
}
inline void pushup(int x) {
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];
};
inline int newnode(int x) {
val[++tot]=x;
siz[tot]=cnt[tot]=1;
return tot;
}
void rotate(int x) {
int y=fa[x],z=fa[fa[x]];
bool ck=check(x);
fa[ch[x][ck^1]]=y;
ch[y][ck]=ch[x][ck^1];
ch[x][ck^1]=y;
fa[y]=x;
fa[x]=z;
if(z) ch[z][ch[z][1]==y]=x;
pushup(y);
pushup(x);
}
void splay(int x) {
for(int f=fa[x]; f; rotate(x),f=fa[x])
if(fa[f]) rotate(check(x)==check(f)?f:x);
root=x;
}
bool insert(int x) {
if(!root) return root=newnode(x),0;
int cur=root,f=0;
while(1) {
if(val[cur]==x) {
cnt[cur]++;
pushup(cur);
pushup(f);
splay(cur);
return 0;
}
f=cur;
cur=ch[cur][x>val[cur]];
if(!cur) {
cur=newnode(x);
fa[cur]=f;
ch[f][x>val[f]]=cur;
pushup(f);
splay(cur);
return 0;
}
}
}
int kth(int x) {
int cur=root;
while(1) {
if(x<=siz[ch[cur][0]]) cur=ch[cur][0];
else {
x-=siz[ch[cur][0]]+cnt[cur];
if(x<=0) return val[cur];
cur=ch[cur][1];
}
}
}
int main() {
n=rd();
m=rd();
int k=0,x;//
for(int i=1; i<=n; i++) data[i]=rd();
for(int i=1; i<=m; i++) x=rd(),que[x]++;
for(int i=1; i<=n; i++) {
insert(data[i]);
while(que[i]--) {
printf("%d\n",kth(++k));
}
}
return 0;
}