萌新求助 刚学主席树
查看原帖
萌新求助 刚学主席树
117307
hyj0824楼主2023/5/2 18:05
#include <algorithm>
#include <bits/stdc++.h>
#include <vector>
using std::cin;
using std::cout;
#define endl '\n'
// using std::endl; // I won't use you forever!
typedef const int& cint;
typedef long long LL;
typedef const LL& cll;

cint maxn = 1e5 + 10;

int n, m, k;

#define now t[id]
#define lch t[now.lid]
#define rch t[now.rid]
#define pre t[pid]
#define m ((l + r) >> 1)

struct node {
    int cnt;
    int lid, rid;
} t[maxn << 5];
int tot, rt[maxn]; // 内存池顶、树的切片(根位置)
// int build(int id, int l, int r); // 完全没必要 空树就空的

void pushup(int id) { now.cnt = lch.cnt + rch.cnt; }

// 权值线段树会直接搜到底 建一个链即可
int mod(int id, int l, int r, int q, int cnt, int pid) {
    if (id == 0) id = ++tot;
    if (l == r) {
        now.cnt = pre.cnt + cnt;
        return id;
    }
    // now.lid = pre.lid, now.rid = pre.rid;
    // 先同步过来(很危险啊 别这样写 会让下一个mod不新建节点)
    int mid = m;
    if (q <= mid)
        now.lid = mod(now.lid, l, mid, q, cnt, pre.lid), now.rid = pre.rid;
    else now.rid = mod(now.rid, mid + 1, r, q, cnt, pre.rid), now.lid = pre.lid;
    pushup(id);
    return id;
}
int kmin(int id, int l, int r, int k, int pid) {
    if (l == r) return l;
    int mid = m;
    int lcnt = t[now.lid].cnt - t[pre.lid].cnt; // 第k小 求左侧
    if (k <= lcnt) return kmin(now.lid, l, mid, k, pre.lid);
    else return kmin(now.rid, mid + 1, r, k - lcnt, pre.rid);
}
#undef m

std::vector<int> a;

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        a.push_back(x);
    }
    std::vector<int> fx(a);
    std::sort(fx.begin(), fx.end());
    int N =
        std::unique(fx.begin(), fx.end()) - fx.begin(); // 总共(不重)的个数
    for (int i = 0; i < n; i++) {
        int pos = std::lower_bound(fx.begin(), fx.end(), a[i]) - fx.begin();
        rt[i + 1] = mod(rt[i + 1], 1, N, pos + 1, 1, rt[i]);
    }
    while (m--) {
        int l, r, k;
        cin >> l >> r >> k;
        cout << fx[kmin(rt[r], 1, N, k, rt[l - 1]) - 1] << endl;
    }
    return 0;
}

70pts,WA了中间3,4,5

2023/5/2 18:05
加载中...