主席树模板 I - 静态区间第k大
Face
题意
数据范围: 1 ≤ n , m ≤ 2 5 , ∣ a [ i ] ∣ ≤ 1 0 9 1\leq n ,m\leq 2^5 , |a[i]| \leq 10^9 1≤n,m≤25,∣a[i]∣≤109
前置技能
Tutorial:
查找更新时空复杂度: O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))
总空间复杂度: O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))
code:
#include
using namespace std;
#define local
#ifdef local
template<class T>
void _E(T x) { cerr << x; }
void _E(double x) { cerr << fixed << setprecision(6) << x; }
void _E(string s) { cerr << "\"" << s << "\""; }
template<class A, class B>
void _E(pair<A, B> x) {
cerr << '(';
_E(x.first);
cerr << ", ";
_E(x.second);
cerr << ")";
}
template<class T>
void _E(vector<T> x) {
cerr << "[";
for (auto it = x.begin(); it != x.end(); ++it) {
if (it != x.begin()) cerr << ", ";
_E(*it);
}
cerr << "]";
}
void ERR() {}
template<class A, class... B>
void ERR(A x, B... y) {
_E(x);
cerr << (sizeof...(y) ? ", " : " ");
ERR(y...);
}
#define debug(x...) do { cerr << "{ "#x" } -> { "; ERR(x); cerr << "}" << endl; } while(false)
#else
#define debug(...) 114514.1919810
#endif
#define _rep(n, a, b) for (ll n = (a); n <= (b); ++n)
#define _rev(n, a, b) for (ll n = (a); n >= (b); --n)
#define _for(n, a, b) for (ll n = (a); n < (b); ++n)
#define _rof(n, a, b) for (ll n = (a); n > (b); --n)
#define oo 0x3f3f3f3f3f3f
#define ll long long
#define db long double
#define eps 1e-3
#define bin(x) cout << bitset<10>(x) << endl;
#define what_is(x) cerr << #x << " is " << x << endl
#define met(a, b) memset(a, b, sizeof(a))
#define all(x) x.begin(), x.end()
#define pii pair
#define pdd pair
#define endl "\n"
const ll mod = 998244353;
const ll maxn = 2e5 + 10;
ll qpow(ll a, ll b) {
ll ret = 1;
for (; b; a = a * a % mod, b >>= 1) {
if (b & 1) {
ret = ret * a % mod;
}
}
return ret;
}
vector<ll> f(maxn), invf(maxn);
ll inv(ll a) {
return qpow(a, mod - 2);
}
void prework() {
f[0] = 1;
_rep(i, 1, maxn - 1) {
f[i] = f[i - 1] * i % mod;
}
invf[maxn - 1] = qpow(f[maxn - 1], mod - 2);
for (ll i = maxn - 2; i >= 0; i--) {
invf[i] = invf[i + 1] * (i + 1) % mod;
}
}
ll C(ll n, ll m) {
if (n > m || m < 0)return 0;
if (n == 0 || m == n) return 1;
ll res = (f[m] * invf[m - n] % mod * invf[n]) % mod;
return res;
}
const ll M = (2e5) + 10;
#define ls tree[now].l
#define rs tree[now].r
ll n, m;
ll k, N;
ll root[M];
ll a[M], ys[M];
struct Node {
ll num;
ll id;
} q[M];
struct node {
ll l, r;
ll size;
} tree[M << 5];
inline ll read() {
ll f = 1, x = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
bool cmp(Node x, Node y) {
return x.num < y.num;
}
void lsh() {
a[q[1].id] = ++N;
ys[N] = q[1].num;
for (ll i = 2; i <= n; i++) {
if (q[i].num != q[i - 1].num) N++;
a[q[i].id] = N;
ys[N] = q[i].num;
}
}
ll build(ll l, ll r) {
ll now = ++k;
if (l < r) {
ll mid = (l + r) >> 1;
ls = build(l, mid);
rs = build(mid + 1, r);
}
return now;
}
ll update(ll pre, ll l, ll r, ll x) {
ll now = ++k;
tree[now].size = tree[pre].size + 1;
ls = tree[pre].l;
rs = tree[pre].r;
if (l < r) {
ll mid = (l + r) >> 1;
if (x > mid) rs = update(rs, mid + 1, r, x);
else
ls = update(ls, l, mid, x);
}
return now;
}
ll query(ll u, ll v, ll l, ll r, ll x) {
if (l == r) return l;
ll t = tree[tree[v].l].size - tree[tree[u].l].size;
ll mid = (l + r) >> 1;
if (x <= t) return query(tree[u].l, tree[v].l, l, mid, x);
else return query(tree[u].r, tree[v].r, mid + 1, r, x - t);
}
signed main() {
n = read();
m = read();
for (ll i = 1; i <= n; i++) {
q[i].num = read();
q[i].id = i;
}
sort(q + 1, q + n + 1, cmp);
lsh();
root[0] = build(1, N);
for (ll i = 1; i <= n; i++)
root[i] = update(root[i - 1], 1, N, a[i]);
for (ll i = 1, r; i <= m; i++) {
r = read();
int l = 1;
int k = i;
printf("%lld\n", ys[query(root[l - 1], root[r], 1, N, k)]);
}
return 0;
}