P1801 黑匣子_NOI导刊2010提高(06)
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=(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根據命令串所得出的輸出串,一個數字一行。
裸的平衡樹treap,當復習了
靠最大值爆我取的INF了調了半天QAQ
Treap還是要熟練掌握得(認真臉)
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<algorithm> #include<climits> typedef long long LL; using namespace std; LL RD(){LL out = 0,flag = 1;char c = getchar();while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}return flag * out;} const LL maxn = 200019,INF = 0xfffffffffffffff; LL ch[maxn][2]; LL val[maxn],dat[maxn]; LL size[maxn],cnt[maxn]; LL tot,root; LL New(LL v){val[++tot] = v,dat[tot] = rand();size[tot] = cnt[tot] = 1;return tot;} void pushup(LL id){size[id] = size[ch[id][0]] + size[ch[id][1]] + cnt[id];} void build(){root = New(-INF),ch[root][1] = New(INF);pushup(root);} void Rotate(LL &id,LL d){LL temp = ch[id][d ^ 1];ch[id][d ^ 1] = ch[temp][d];ch[temp][d] = id;id = temp;pushup(ch[id][d]),pushup(id);} void insert(LL &id,LL v){if(!id){id = New(v);return ;}if(val[id] == v){cnt[id]++;pushup(id);return ;}LL d = v < val[id] ? 0 : 1;insert(ch[id][d],v);if(dat[id] < dat[ch[id][d]])Rotate(id,d ^ 1);pushup(id);} LL get_val(LL id,LL rank){if(!id)return INF;if(size[ch[id][0]] >= rank)return get_val(ch[id][0],rank);else if(size[ch[id][0]] + cnt[id] >= rank)return val[id];else return get_val(ch[id][1],rank - size[ch[id][0]] - cnt[id]);} LL num,na; LL ori[maxn],ask[maxn],p = 1; int main(){num = RD();na = RD();for(LL i = 1;i <= num;i++)ori[i] = RD();for(LL i = 1;i <= na;i++)ask[RD()]++;build();for(LL i = 1;i <= num;i++){insert(root,ori[i]);while(ask[i]--)printf("%lld\n",get_val(root,++p));}return 0;}轉載于:https://www.cnblogs.com/Tony-Double-Sky/p/9291400.html
總結
以上是生活随笔為你收集整理的P1801 黑匣子_NOI导刊2010提高(06)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue组件通信之父组件主动获取子组件数据
- 下一篇: 关于线段树