[DSAA-Lab6]F. Balanced Binary Tree

数据结构与算法分析A Lab 7 F题题解

Description

In a company, there are thousands of employees, your work is to check the information about the salary. There is a minimum salary(it is the same for everyone), whenever someone’s salary is less than this minimum salary, he(or she) will leave the company. There are n operations, and each operation is one of the following cases:

Insert x: a fresh man joins the company, whose salary is x.

Add x: increase everyone’s salary by x.

Subtract x: reduce everyone’s salary by x.

Query x: print the k-th maximum salary in this company.

At first, the company has 0 employees.

Input

The first line will be an integer T, which is the number of test cases. (1 <= T <= 10). For each test case, the first line will be two integers n(1 <= n <= 105) and m(1 <= m <= 106), n is the number of operations, m is the minimum salary. Then followed by n lines, each line will be one of the following cases:

I x: Insert x.

A x: Add x.

S x: Subtract x.

Q x: Query x.

Output

For each “Query”, print the k-th maximum salary in this company, if the number of employees is less than k, print “-1”. At last, print the number of employees who has leave the company. We guarantee that no one will come back to the company after he(or she) leaves.

Sample Input

1
9 10
I 60
I 70
S 50
Q 2
I 30
S 15
A 5
Q 1
Q 2

Sample Output

10
20
-1
2

思路

原题郁闷的出纳员。。

我觉得刚学就能做出来的同学真的tql

Solution

Code

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <algorithm>
const int N = 1e5 + 10;
using namespace std;
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
struct tree
{
    int l, r, val, rnd, sz;
} tr[N];
int n, mn, Delta, leave, root = 0;
struct Treap
{
    int cnt;
    Treap() { cnt = 0; }
    void update(int k)
    {
        tr[k].sz = tr[tr[k].l].sz + tr[tr[k].r].sz + 1;
    }
    void Rturn(int &k)
    {
        int t = tr[k].l;
        tr[k].l = tr[t].r;
        tr[t].r = k;
        update(k);
        update(t);
        k = t;
    }
    void Lturn(int &k)
    {
        int t = tr[k].r;
        tr[k].r = tr[t].l;
        tr[t].l = k;
        update(k);
        update(t);
        k = t;
    }
    void Ins(int &k, int x)
    {
        if (k == 0)
        {
            cnt++;
            k = cnt;
            tr[k].rnd = rand();
            tr[k].val = x;
            tr[k].l = tr[k].r = 0;
            tr[k].sz = 1;
            return;
        }
        tr[k].sz++;
        if (x < tr[k].val)
        {
            Ins(tr[k].l, x);
            if (tr[tr[k].l].rnd < tr[k].rnd)
                Rturn(k);
        }
        else
        {
            Ins(tr[k].r, x);
            if (tr[tr[k].r].rnd < tr[k].rnd)
                Lturn(k);
        }
    }
    int Del(int &k, int x)
    {
        int t;
        if (k == 0)
            return 0;
        if (tr[k].val < x)
        {
            t = tr[tr[k].l].sz + 1;
            k = tr[k].r;
            return t + Del(k, x);
        }
        else
        {
            t = Del(tr[k].l, x);
            tr[k].sz -= t;
            return t;
        }
    }
    int Find(int k, int x)
    {
        if (tr[tr[k].l].sz + 1 == x)
            return tr[k].val + Delta;
        else if (tr[tr[k].l].sz + 1 < x)
            return Find(tr[k].r, x - tr[tr[k].l].sz - 1);
        else
            return Find(tr[k].l, x);
    }
} Tr;
void solve()
{   
    n = read(), mn = read();
    // Tr.cnt = 0;
    memset(tr, 0, sizeof tr);
    char opt[10];
    int x;
    root = Tr.cnt = Delta = leave = 0;
    while (n--)
    {
        scanf("%s", opt);
        x = read();
        if (opt[0] == 'I')
            if (x >= mn)
                Tr.Ins(root, x - Delta);
        if (opt[0] == 'A')
            Delta += x;
        if (opt[0] == 'S')
        {
            Delta -= x;
            leave += Tr.Del(root, mn - Delta);
        }
        if (opt[0] == 'Q')
        {
            if (x > tr[root].sz)
                printf("-1");
            else
                printf("%d", Tr.Find(root, tr[root].sz - x + 1));
            printf("\n");
        }
    }
    printf("%d\n", leave);
}
int main()
{
    int T; scanf("%d", &T);
    while (T--)
        solve();
    return 0;
}
评论区

Gitalking ...

Markdown is supported

Be the first guy leaving a comment!