洛谷P2617 Dynamic Rankings 题解 树套树(树状数组 套 权值线段树)
题目链接:https://www.luogu.com.cn/problem/P2617
这题应该算模板题吧。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5, inf = 1e9;
int n, m, a[maxn];
struct SegmentTree {
int tr[maxn*300], ls[maxn*300], rs[maxn*300], idx;
void push_up(int u) {
int l = ls[u], r = rs[u];
tr[u] = tr[l] + tr[r];
}
void add(int p, int val, int l, int r, int &u) {
if (!u) u = ++idx;
if (l == r) {
tr[u] += val;
return;
}
int mid = l + r >> 1;
(p <= mid) ? add(p, val, l, mid, ls[u]) : add(p, val, mid+1, r, rs[u]);
push_up(u);
}
int query(int L, int R, int l, int r, int u) {
if (!u) return 0;
if (L <= l && r <= R) return tr[u];
int res = 0, mid = l + r >> 1;
if (L <= mid) res += query(L, R, l, mid, ls[u]);
if (R > mid) res += query(L, R, mid+1, r, rs[u]);
return res;
}
int kth(int l, int r, int k, vector<int> &t1, vector<int> &t2) {
if (l == r) return l;
int cnt = 0, mid = l + r >> 1;
for (auto u : t1) {
int l = ls[u];
cnt += tr[l];
}
for (auto u : t2) {
int l = ls[u];
cnt -= tr[l];
}
if (cnt >= k) {
for (auto &u : t1) u = ls[u];
for (auto &u : t2) u = ls[u];
return kth(l, mid, k, t1, t2);
}
else {
for (auto &u : t1) u = rs[u];
for (auto &u : t2) u = rs[u];
return kth(mid+1, r, k - cnt, t1, t2);
}
}
} seg_t;
struct BIT {
int tr[maxn];
int lowbit(int x) { return x & -x; }
void add(int p, int x, int val) {
for (int i = p; i <= n; i += lowbit(i))
seg_t.add(x, val, 0, inf, tr[i]);
}
void get_tr(int p, vector<int> &vec) {
for (int i = p; i; i -= lowbit(i))
vec.push_back(tr[i]);
}
int kth(int l, int r, int k) {
vector<int> t1, t2;
get_tr(r, t1);
get_tr(l-1, t2);
// cout << "t1: "; for (auto u : t1) cout << u << ", "; cout << endl;
// cout << "t2: "; for (auto u : t2) cout << u << ", "; cout << endl;
int res = seg_t.kth(0, inf, k, t1, t2);
return res;
}
} bit;
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", a+i);
bit.add(i, a[i], 1);
}
while (m--) {
char op[2];
scanf("%s", op);
if (op[0] == 'C') { // C x y
int x, y;
scanf("%d%d", &x, &y);
bit.add(x, a[x], -1);
a[x] = y;
bit.add(x, a[x], 1);
}
else { // Q l r k
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
int ans = bit.kth(l, r, k);
printf("%d\n", ans);
}
}
return 0;
}
浙公网安备 33010602011771号