1. 程式人生 > >[LUOGU] P1801 黑匣子_NOI導刊2010提高(06)

[LUOGU] P1801 黑匣子_NOI導刊2010提高(06)

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=(31,一428,-10002)。 2.u(1),u(2),…u(N):表示第u(j)個元素被放進了Black Box裡後就出現一個GET命令。例如上面的例子中u=(l,266)。輸入資料不用判錯。 輸入輸出格式 輸入格式: 第一行,兩個整數,M,N。 第二行,M個整數,表示A(l) ……A(M)。 第三行,N個整數,表示u(l) …u(N)。 輸出格式: 輸出Black Box根據命令串所得出的輸出串,一個數字一行。 輸入輸出樣例 輸入樣例#17 4 3 1 -4 2 8 -1000 2 1 2
6 6 輸出樣例#13 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; }