势能分析平衡树,splay或treap都可以
放个指针版的就跑
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i=a;i<=b;++i) 4 const int maxn=100010; 5 template <class T> inline bool check_Max(T &x, const T&y) { return x<y?x=y,false:true;} 6 template <class T> inline bool check_Min(T &x, const T&y) { return x>y?x=y,false:true;} 7 inline int gi() { 8 int x=0; char o; bool f=true; for(;!isdigit(o=getchar());) if(o=='-') f=false; 9 for(;isdigit(o);o=getchar()) x=(x<<1)+(x<<3)+(o&15); return f?x:~x+1; 10 } 11 struct node {int v,ky,sz,lz; node *ls,*rs;}*rt,*nul,pool[maxn],*pis=pool; 12 inline void init() { nul=pis; nul->ls=nul->rs=nul; nul->lz=nul->sz=0; rt=nul;} 13 node *newnode(int vl) { node *k=++pis; k->ls=k->rs=nul; k->v=vl; k->ky=rand(); k->lz=0; k->sz=1; return k;} 14 inline void add(node *&x,int vl) { x->v+=vl; x->lz+=vl; return ;} 15 inline void pd(node *&x) { 16 if(x->lz) {if(x->ls!=nul) add(x->ls,x->lz); if(x->rs!=nul) add(x->rs,x->lz);}x->lz=0; 17 } 18 inline void up(node *&x) { x->sz=x->ls->sz+x->rs->sz+1; } 19 inline void mrg(node *&c,node *x,node *y) { 20 if(x==nul||y==nul) {c=x==nul?y:x; return;} 21 pd(x); pd(y); 22 if(x->ky < y->ky) c=x,mrg(c->rs,x->rs,y); 23 else c=y,mrg(c->ls,x,y->ls); up(c); 24 } 25 inline void spl(node *c,node *&x,node *&y,int rk) { 26 if(c==nul) { x=y=nul; return;} 27 pd(c); 28 if(c->v <= rk) x=c,spl(c->rs,x->rs,y,rk); 29 else y=c,spl(c->ls,x,y->ls,rk); up(c); 30 } 31 inline void insert(int vl) { 32 node *x,*y; spl(rt,x,y,vl); 33 mrg(x,x,newnode(vl)); mrg(rt,x,y); 34 } 35 int find(node *&x,int rk) { 36 if(x->ls->sz+1==rk) return x->v; 37 pd(x); 38 if(rk<=x->ls->sz) return find(x->ls,rk); 39 return find(x->rs,rk-x->ls->sz-1); 40 } 41 inline void rec(node *&now,node *&x,int vl) { 42 if(x==nul) return; pd(x); rec(now,x->ls,vl); rec(now,x->rs,vl); 43 x->ls=x->rs=nul; x->sz=1; x->v-=vl; 44 node *x1,*y1; spl(now,x1,y1,x->v); mrg(x1,x1,x); mrg(now,x1,y1); 45 } 46 inline void cg(int k) { 47 node *x,*y,*z; spl(rt,x,y,k); spl(y,y,z,k<<1); 48 add(z,-k); rec(x,y,k); mrg(rt,x,z); 49 } 50 int n,m; 51 int main() { 52 #ifndef ONLINE_JUDGE 53 freopen("3.in","r",stdin); 54 freopen("a.out","w",stdout); 55 #endif 56 n=gi();m=gi(); 57 init(); 58 rep(i,1,n) insert(gi()); 59 rep(i,1,m) { 60 int opt=gi(),K=gi(); 61 if(opt==1) printf("%d\n",find(rt,K)); 62 else cg(K); 63 } 64 return 0; 65 }