Super Mario HDU

原题链接

  • 题意:静态区间询问比 (k) 大的数、小的数。
  • 题解:主席树,但是问题是离散化的时候要注意,那个 (k) 也得加入离散化。
  • 代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>


using namespace std;
const int N = 2e5 * 80;
int a[N], b[N], rt[N], nn;
struct q{
    int l, r, k;
}Q[N];
struct President_Tree {
    struct node {
        int l, r, data;
    }tr[N];
    int idx;
    inline void create(int &p, int q, int l, int r, int num) {
        p = ++idx;
        tr[p] = tr[q];
        tr[p].data++;
        if (l == r)return;
        int mid = l + r >> 1;
        if (num <= mid) create(tr[p].l, tr[q].l, l, mid, num);
        else create(tr[p].r, tr[q].r, mid + 1, r, num);
    }
    inline int ask(int p, int q, int l, int r, int k) {
        int mid = l + r >> 1;
        if (l == r)return tr[p].data - tr[q].data;//这个一开始没想明白,直接返回的 tr[p].data;
        if (mid >= k) {//等于号要想一下为啥
            return ask(tr[p].l, tr[q].l, l, mid, k);
        } else {
            return ask(tr[p].r, tr[q].r, mid + 1, r, k) + tr[tr[p].l].data - tr[tr[q].l].data;
        }
    }
}T;

int cas = 0;
signed main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        T.idx = 0;
        int n, m;scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]),b[i] = a[i];
        printf("Case %d:
", ++cas);
        for (int i = 1; i <= m; i ++) {
            int l, r, k;
            scanf("%d%d%d", &l, &r, &k);
            l++,r++;
            Q[i] = {l, r, k};
            b[n+ i] = k;
        }
        sort(b + 1, b + 1 + n + m);
        nn = unique(b  + 1, b + 1 + m+n) - b - 1;
        for (int i = 1; i <= n; i ++) a[i] = lower_bound(b + 1, b + 1 + nn, a[i])-b, T.create(rt[i], rt[i-1], 1, nn, a[i]);
        for (int i = 1; i <= m; i ++) {
            int k = Q[i].k, r = Q[i].r, l = Q[i].l;
            k = lower_bound(b + 1, b + 1 + nn, k) - b;
            printf("%d
", T.ask(rt[r], rt[l-1], 1, nn, k));
        }
    }
}
原文地址:https://www.cnblogs.com/Xiao-yan/p/14708052.html