LOJ10145郁闷的出纳员

传送门: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 }
View Code
原文地址:https://www.cnblogs.com/gryzy/p/10656926.html