1. 程式人生 > >洛谷 1486 郁悶的出納員【Treap】

洛谷 1486 郁悶的出納員【Treap】

printf image inno ons names 同時 style ret view

技術分享圖片

【題意概述】

  要求維護一個序列支持以下操作:

  1,插入元素x;

  2,把序列的所有元素加上x;

  3,把序列的所有元素減去x,同時低於一個給定的下限的元素馬上被刪除;

  4,詢問序列中第k大的元素。

【題解】

  Treap

  用一個delta記錄元素的增減情況,即實際上的元素的值應該是qval(root,x)+delta,那麽插入元素時插入的應該是Val-delta.

  每次加減操作的時候改delta和下限Minwage,加操作的時候Minwage-=val(即下限相對於元素值減小了Val),減操作的時候Minwage+=val(即下限相對於元素值增加了Val)

  每次減操作時分裂出序列裏小於Minwage的元素,把它們扔掉即可。

技術分享圖片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #define ls (a[u].l)
 4 #define rs (a[u].r)
 5 using namespace std;
 6 const int maxn=200010;
 7 int n,k,x,y,z,v,tot,root,Minwage,Minnow,delta;
 8 char c,c2;
 9 struct treap{int l,r,v,rnd,size;}a[maxn];
10 inline int read(){
11     int k=0,f=1; char
c=getchar(); 12 while(c<0||c>9)c==-&&(f=-1),c=getchar(); 13 while(0<=c&&c<=9)k=k*10+c-0,c=getchar(); 14 return k*f; 15 } 16 void newnode(int val){a[++tot]=(treap){0,0,val,rand()+1,1};} 17 void update(int u){a[u].size=a[ls].size+a[rs].size+1;} 18 void split(int
u,int k,int &x,int &y){ 19 if(!k){x=0; y=u; return;} 20 if(a[u].size==k){x=u; y=0; return;} 21 if(a[ls].size>=k) split(ls,k,x,ls),y=u; 22 else split(rs,k-a[ls].size-1,rs,y),x=u; 23 update(u); 24 } 25 int merge(int x,int y){ 26 if(!x||!y) return x+y; 27 if(a[x].rnd<a[y].rnd){a[x].r=merge(a[x].r,y); update(x); return x;} 28 else{a[y].l=merge(x,a[y].l); update(y); return y;} 29 } 30 int qrank(int u,int val){ 31 if(!u) return 0; 32 return a[u].v>=val?qrank(ls,val):qrank(rs,val)+a[ls].size+1; 33 } 34 int qval(int u,int k){ 35 if(a[ls].size+1==k) return a[u].v; 36 return a[ls].size>=k?qval(ls,k):qval(rs,k-a[ls].size-1); 37 } 38 int main(){ 39 srand(20020705); 40 n=read(); Minwage=Minnow=read(); 41 while(n--){ 42 c=getchar(); 43 while(c!=I&&c!=A&&c!=S&&c!=F) c=getchar(); 44 c2=getchar(); v=read(); 45 if(c==I&&v>=Minwage){ 46 split(root,qrank(root,v-delta),x,y); 47 newnode(v-delta); root=merge(merge(x,tot),y); 48 } 49 if(c==A) Minnow-=v,delta+=v; 50 if(c==S){ 51 Minnow+=v; delta-=v; 52 split(root,qrank(root,Minnow),x,y); 53 root=y; 54 } 55 if(c==F) printf("%d\n",a[root].size>=v?qval(root,a[root].size-v+1)+delta:-1); 56 } 57 return printf("%d",tot-a[root].size),0; 58 }
View Code

洛谷 1486 郁悶的出納員【Treap】