传送门:https://loj.ac/problem/10145
简单的平衡树
————————————————————————————————————
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 int n,minv,lk; 5 struct node 6 { 7 int val,lc,rc,siz,rd,delt; 8 }tr[maxn]; 9 int cnt,root; 10 int newnode(int v) 11 { 12 tr[++cnt].val=v; 13 tr[cnt].lc=tr[cnt].rc=0; 14 tr[cnt].siz=1; 15 tr[cnt].rd=rand(); 16 tr[cnt].delt=0; 17 return cnt; 18 } 19 void update(int cur) 20 { 21 tr[cur].siz=tr[tr[cur].lc].siz+tr[tr[cur].rc].siz+1; 22 } 23 void down(int cur) 24 { 25 if(!cur)return ; 26 if(tr[cur].delt) 27 { 28 tr[tr[cur].lc].val+=tr[cur].delt; 29 tr[tr[cur].rc].val+=tr[cur].delt; 30 tr[tr[cur].lc].delt+=tr[cur].delt; 31 tr[tr[cur].rc].delt+=tr[cur].delt; 32 tr[cur].delt=0; 33 } 34 } 35 int merge(int x,int y) 36 { 37 if(x*y==0)return x+y; 38 if(tr[x].rd<tr[y].rd) 39 { 40 down(x); 41 tr[x].rc=merge(tr[x].rc,y); 42 update(x); 43 return x; 44 } 45 else 46 { 47 down(y); 48 tr[y].lc=merge(x,tr[y].lc); 49 update(y); 50 return y; 51 } 52 } 53 void splitm(int cur,int v,int &x,int &y) 54 { 55 if(!cur)x=y=0; 56 else 57 { 58 if(tr[tr[cur].lc].siz+1<=v) 59 { 60 down(cur); 61 x=cur; 62 splitm(tr[cur].rc,v-tr[tr[cur].lc].siz-1,tr[cur].rc,y); 63 } 64 else 65 { 66 down(cur); 67 y=cur; 68 splitm(tr[cur].lc,v,x,tr[cur].lc); 69 } 70 update(cur); 71 } 72 } 73 void splitv(int cur,int v,int &x,int &y) 74 { 75 if(!cur)x=y=0; 76 else 77 { 78 down(cur); 79 if(tr[cur].val<=v) 80 { 81 x=cur; 82 splitv(tr[cur].rc,v,tr[cur].rc,y); 83 } 84 else 85 { 86 y=cur; 87 splitv(tr[cur].lc,v,x,tr[cur].lc); 88 } 89 update(cur); 90 } 91 } 92 93 char s[3]; 94 void insert(int v) 95 { 96 if(v<minv) 97 { 98 return ; 99 } 100 int x,y; 101 splitv(root,v,x,y); 102 root=merge(merge(x,newnode(v)),y); 103 } 104 void add(int v) 105 { 106 tr[root].val+=v; 107 tr[root].delt+=v; 108 int x,y; 109 if(v<0) 110 { 111 splitv(root,minv-1,x,y); 112 lk+=tr[x].siz; 113 root=y; 114 } 115 } 116 int kth(int cur,int k) 117 { 118 while(cur) 119 { 120 down(cur); 121 if(tr[tr[cur].lc].siz+1==k)return tr[cur].val; 122 else if(tr[tr[cur].lc].siz>=k)cur=tr[cur].lc; 123 else 124 { 125 k-=tr[tr[cur].lc].siz+1; 126 cur=tr[cur].rc; 127 } 128 } 129 } 130 void find(int v) 131 { 132 if(!root || tr[root].siz<v || v<=0) 133 { 134 puts("-1"); 135 return ; 136 } 137 int x,y; 138 splitm(root,v-1,x,y); 139 printf("%d ",kth(y,1)); 140 root=merge(x,y); 141 } 142 int main() 143 { 144 scanf("%d%d",&n,&minv); 145 for(int x,i=0;i<n;++i) 146 { 147 scanf("%s%d",s,&x); 148 if(s[0]=='I')insert(x); 149 else if(s[0]=='A')add(x); 150 else if(s[0]=='S')add(-x); 151 else find(tr[root].siz-x+1); 152 } 153 printf("%d ",lk); 154 return 0; 155 }