BZOJ1503[NOI2004] Depressed Teller - Balanced Tree

Description
OIER is a large specialized software company with tens of thousands of employees. As a cashier, one of my tasks is to count the wages of each employee. It would have been a good job, but it was frustrating that our boss was fickle and often adjusted his employees' salaries. If he is in a good mood, he may add an equal amount to each employee's salary. Conversely, if they are in a bad mood, their wages may be deducted by the same amount. I really don't know what else he does other than adjust wages. The frequent adjustment of wages is very disgusting for employees, especially when the collective salary is deducted. Once an employee finds that his salary is lower than the lower limit of the salary stipulated in the contract, he will immediately leave the company angrily and never come back. . The lower bound of the salary of each employee is uniformly stipulated. Every time a person leaves the company, I delete his salary file from the computer, and similarly, every time the company hires a new employee, I have to create a new salary file for him. The boss often comes to me to ask about the salary. He does not ask the salary of a specific employee, but asks how much the employee with the highest salary is getting. Every so often, I have to do a lengthy sort of tens of thousands of employees and tell him the answer. Well, now you know a lot about my work. As you can guess, I would like to ask you to program a salary statistics program. How, it's not very difficult, is it?
The first line of Input
has two non-negative integers n and min. n indicates how many commands there are below, and min indicates the salary lower bound.
The next n lines, each line represents a command. The command can be one of the following four types:
Name Format Function
I Command I_k Create a new salary file, the initial salary is k.
If an employee's initial salary is lower than the salary lower bound, he will immediately leave the company.
A command A_k to add k to each employee's salary
S command S_k to deduct k from each employee's salary
F command F_k to query the k-th highest salary
_ (underscore) represents a space, k in the I command, A command, and S command is a non-negative integer, and k in the F command is a positive integer.
In the beginning, it can be assumed that there is not a single employee in the company.
The number of I commands does not exceed 100000 The total number of
A commands and S commands does not exceed 100 The number of F commands is incremented by one. For each F command, your program should output one line, containing only one integer, the salary of the current employee with the kth highest salary , or -1 if k is greater than the number of current employees. The last line of the output file contains an integer, the total number of employees who have left the company. Sample Input 9 10









I 60

I 70

S 50

F 2

I 30

S 15

A 5

F 1

F 2

Sample Output
10

20

-1

2


This question can obviously be seen as a balanced tree, we only need to build a Splay. Each time you join, you can delete a point.
But here's a little trick. Since we use minnum to check whether the employee has left, if we want to subtract x from all points at a certain moment, it is equivalent to adding minnum to x, and then go to the operation. When adding a new point, add the value of the new point to minnum minus the original minnum (the newly added point will not be affected). Such a small tip can reduce a lot of operations.
#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
int read(){
    char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
    while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
int n,x,sz,knum,now,tot=0,dist,root;
char c;
struct Splay{
    int son[MAXN][2],ct[MAXN],val[MAXN],siz[MAXN],fa[MAXN];
    void clear(int k){
        son[k][1]=son[k][0]=ct[k]=val[k]=siz[k]=fa[k]=0;
    }
    void up(int k){
        siz[k]=siz[son[k][0]]+siz[son[k][1]]+ct[k];
    }
    int get(int k){
        return k==son[fa[k]][1];
    }
    void insert(int &k,int num,int pos){
        if(!k){
            k=++sz;fa[sz]=pos;ct[sz]=siz[sz]=1;val[sz]=num;dist=k;
            return;
        }
        if(num==val[k]){
            dist=k;siz[k]++;ct[k]++;return;
        }
        insert(son[k][num>val[k]],num,k);
        up(k);
    }
    void ahe(int k,int x,int vis){
        if(!k&&vis){
            dist=2e9;return;
        }
        if(!k) return;
        if(x>val[k]) ahe(son[k][1],x,vis==1);
        else dist=k,ahe(son[k][0],x,0);
    }
    void rotate(int &k){
        int f=fa[k],gran=fa[f];int d1=get(k),d2=get(f);
        son[f][d1]=son[k][d1^1];fa[son[k][d1^1]]=f;
        fa[f]=k;fa[k]=gran;son[k][d1^1]=f;
        if(gran) son[gran][d2]=k;up(f);up(k);
    }
    void splay(int k){
        for(int f=k;f=fa[k];rotate(k))
           if(fa[f]) rotate(get(f)==get(k)?f:k);
        root=k;
    }
    int searchRank(int k,int x){
        if(!k) return -1;
        if(x<=siz[son[k][1]]) return searchRank(son[k][1],x);
        x-=siz[son[k][1]];
        if(x<=ct[k]) return val[k];
        x-=ct[k];
        return searchRank(son[k][0],x);
    }
}T;
int main()
{
    n=read();knum=read();now=knum;
    for(int i=1;i<=n;i++){
        cin>>c>>x;
        if(c=='I'){
            if(x>=knum){
                T.insert(root,x+(now-knum),0);
                T.splay(dist);
            }
        }
        if(c=='S'){
            now+=x;
            dist=0;T.ahe(root,now,1);
            if(!dist) continue;
            if(dist==2e9){  //这里有一个问题,就是如果x大于splay里所有数,则后继依旧是0,但我们需要删除所有
            //的点,所以我们在写ahe的时候需要加上特判,如果一直向右走,则删除所有的点
                tot+=T.siz[root];root=0;T.clear(root);continue;
            }
            T.splay(dist);
            T.siz[root]-=T.siz[T.son[root][0]];
            tot+=T.siz[T.son[root][0]];T.son[root][0]=0;
        }
        if(c=='A'){
            now-=x;
        }
        if(c=='F'){
            int fd=T.searchRank(root,x);
            if(fd!=-1) printf("%d\n",T.searchRank(root,x)-(now-knum));
            else puts("-1");
        }
    }
    printf("%d",tot);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325613730&siteId=291194637