1. 程式人生 > >2018年東北農業大學春季校賽 L-wyh 【線段樹】

2018年東北農業大學春季校賽 L-wyh 【線段樹】

題目描述 
你們wyh學長小時候住在河邊,因為周圍的生態環境非常好,所以經常會有天鵝浮在湖面上,每隻天鵝都長得不一樣,它們偶爾排成一排,偶爾分散開,偶爾也會去其他河畔,wyh學長為了統計它們的個數,編了一個程式賦予它們一個“萌”值,但是這些天鵝很不聽話,一會兒會從別的地方游過來一兩隻,一會兒又會在統計過程中游走一兩隻,現在請你幫他完成統計任務。
輸入描述:
共有T(T<=10)組資料,每組資料第一行為兩個數 N, M (N,M <= 500000),代表有N只天鵝和M次操作,接下來一行是N個數字,下面M行首先會輸入一個字串S,接著會有三類操作,如果S是“insert”,接著輸入一個正整數a,代表插入一隻“萌”值為a的天鵝,如果S是“delete”,接著輸入一個正整數a,代表刪除一隻“萌”值為a的天鵝,如果S是“query”,接著輸入一個正整數k,代表查詢“萌”值第k大的天鵝。
萌值為[1,1000000000],並且保證一定存在第k大
輸出描述:
對應每次詢問,輸出詢問結果。
示例1
輸入


1
5 4
6 4 2 9 1
query 2
insert 7
delete 6
query 2
輸出


6

7

思路與  這篇連結相似,這裡就不做詳細介紹了;

#include<bits/stdc++.h>
using namespace std;
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define mms(x, y) memset(x, y, sizeof x)
#define MAX 1000000
int tree[MAX << 2];
void PushUp(int rt)
{
    tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}
void Update(int rt, int l, int r, int i, int v)
{
    if(l == r)
    {
        tree[rt] += v;
        return;
    }
    int mid = (l + r) >> 1;
    if(i <= mid)
        Update(lson, i, v);
    else
        Update(rson, i, v);
    PushUp(rt);
}
int Query(int rt, int l, int r, int k)
{
    if(l == r)
        return l;
    int mid = (l + r) >> 1;
    if(tree[rt << 1 | 1] >= k)
        return Query(rson, k);
    else
        return Query(lson, k - tree[rt << 1 | 1]);
}

int main()
{
    int N;
    scanf("%d", &N);
    while(N--)
    {
        int n, m;
        scanf("%d%d", &n, &m);
        mms(tree, 0);
        for(int i = 0, x; i < n; i++)
        {
            scanf("%d", &x);
            Update(1, 1, MAX, x, 1);
        }
        char s[30];
        for(int k = 0, x; k < m; k++)
        {
            scanf("%s%d", s, &x);
            if(s[0] == 'q')
                printf("%d\n", Query(1, 1, MAX, x));
            if(s[0] == 'i')
                Update(1, 1, MAX, x, 1);
            if(s[0] == 'd')
                Update(1, 1, MAX, x, -1);
        }
    }
    return 0;
}