随机跳的。
一眼带修第 \(\text{k}\) 大,平衡树 / 权值线段树 / set
随便搞就行。
(set
可能要双 \(\log\),所以没写)
很快啊,权值线段树就 \(\text{A}\) 了。直接跑到最优解第二页。
敲一遍警钟,是由大到小第 \(k\) ,不是由小到大。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <unordered_map>
#define rep(i, a, b) for (int i = (a); i <= (b); i ++ )
#define rop(i, a, b) for (int i = (a); i < (b); i ++ )
#define dep(i, a, b) for (int i = (a); i >= (b); i -- )
#define dop(i, a, b) for (int i = (a); i > (b); i -- )
using namespace std;
using LL = long long;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
const int N = 100010;
int n, m, w[N];
vector<int> v;
struct Queries {
int op, v;
}q[N];
unordered_map<int, int> cnt;
int find(int x) {
return lower_bound(v.begin(), v.end(), x) - v.begin();
}
struct Tree {
int l, r;
int sum;
}tr[N << 2];
#define ls u << 1
#define rs u << 1 | 1
void pushup(int u) {
tr[u].sum = tr[ls].sum + tr[rs].sum;
}
void build(int u, int l, int r) {
tr[u] = {l, r, 0};
if (l == r) {
tr[u].sum = cnt[v[r]];
return;
}
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
pushup(u);
}
void modify(int u, int x) {
if (x == tr[u].l && x == tr[u].r) {
tr[u].sum ++ ;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
modify(x <= mid ? ls : rs, x);
pushup(u);
}
int query(int u, int k) {
if (tr[u].l == tr[u].r) return v[tr[u].l];
if (tr[rs].sum < k) return query(ls, k - tr[rs].sum);
else return query(rs, k);
}
int main() {
scanf("%d%d", &n, &m);
rep(i, 1, n) scanf("%d", &w[i]);
rep(i, 1, m) scanf("%d%d", &q[i].op, &q[i].v);
rep(i, 1, n) v.push_back(w[i]), cnt[w[i]] ++ ;
rep(i, 1, m) v.push_back(q[i].v);
sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end());
// 离散化
build(1, 0, v.size() - 1);
rep(i, 1, m) {
if (q[i].op == 1) printf("%d\n", query(1, q[i].v));
else modify(1, find(q[i].v));
}
return 0;
}
算是板子吧,挺好写的。(为什么块状链表跑的比线段树还快?)
标签:宝石,管理系统,int,线段,tr,mid,P2343,using,include From: https://www.cnblogs.com/LcyRegister/p/17040067.html