HDU2665 Kth number(主席树,离散化)

Problem Description

Give you a sequence and ask you the kth big number of a inteval.

Input

The first line is the number of the test cases. For each test case,
the first line contain two integer n and m (n, m <= 100000), indicates
the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence. Each of
following m lines contains three integers s, t, k. [s, t] indicates
the interval and k indicates the kth big number in interval [s, t]

Output

For each test case, output m lines. Each line contains the kth big
number.

Sample Input

1 
10 1 
1 4 2 3 5 6 7 8 9 0 
1 3 2 

Sample Output

2

思路

普通的主席树求给定区间第k大,如果不会的去看我以前的博客。。

代码

#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
const int N = 2e5 + 10;
const int inf = 0x3f3f3f3f;
int node_cnt, n, m;
int sum[N << 5], rt[N], lc[N << 5], rc[N << 5];
int a[N], b[N], p; //原序列和离散序列和修改点
void build(int &t, int l, int r)
{
    t = ++node_cnt;
    if (l == r)
        return;
    int mid = (l + r) >> 1;
    build(lc[t], l, mid);
    build(rc[t], mid + 1, r);
}
int modify(int o, int l, int r)
{
    int oo = ++node_cnt;
    lc[oo] = lc[o];
    rc[oo] = rc[o];
    sum[oo] = sum[o] + 1;
    if (l == r)
        return oo;
    int mid = (l + r) >> 1;
    if (p <= mid)
        lc[oo] = modify(lc[oo], l, mid);
    else
        rc[oo] = modify(rc[oo], mid + 1, r);
    return oo;
}

int query(int u, int v, int l, int r, int k) //求u,v这两棵线段树的差的树中的第k大
{
    int mid = (l + r) >> 1, ans;
    int x = sum[lc[v]] - sum[lc[u]];
    if (l == r)
        return l;
    if (x >= k)
        ans = query(lc[u], lc[v], l, mid, k);
    else
        ans = query(rc[u], rc[v], mid + 1, r, k - x);
    return ans;
}
void init()
{
    node_cnt = 0;
}
int main()
{
    //freopen("in.txt", "r", stdin);
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d%d", &n, &m);
        init();
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            b[i] = a[i];
        }
        sort(b + 1, b + n + 1);
        int q = unique(b + 1, b + n + 1) - (b + 1);
        build(rt[0], 1, q);
        for (int i = 1; i <= n; i++)
        {
            p = lower_bound(b + 1, b + q + 1, a[i]) - b;
            rt[i] = modify(rt[i - 1], 1, q);
        }
        int l, r, k;
        while (m--)
        {
            scanf("%d%d%d", &l, &r, &k);
            int ans = query(rt[l - 1], rt[r], 1, q, k);
            printf("%d\n", b[ans]);
        }
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/riba2534/article/details/81136882
今日推荐