可持久化数组
例题
可持久化线段树
算法流程
复杂度分析
例题
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
int a[N], b[N], root[N], cnt, n, m;
struct{int L, R, sum;
} tree[N << 5];
int build(int pl, int pr){int rt = ++cnt;tree[rt].sum = 0;int mid = (pl + pr) >> 1;if(pl < pr){tree[rt].L = build(pl, mid);tree[rt].R = build(mid + 1, pr);}return rt;
}
int modify(int pre, int pl, int pr, int x){int rt = ++cnt;tree[rt].L = tree[pre].L;tree[rt].R = tree[pre].R;tree[rt].sum = tree[pre].sum + 1;int mid = (pl + pr) >> 1;if(pl < pr){if(x <= mid)tree[rt].L = modify(tree[pre].L, pl, mid, x);elsetree[rt].R = modify(tree[pre].R, mid + 1, pr, x);}return rt;
}
int query(int u, int v, int pl, int pr, int k){if(pl == pr)return pl;int x = tree[tree[v].L].sum - tree[tree[u].L].sum;int mid = (pl + pr) >> 1;if(x >= k)return query(tree[u].L, tree[v].L, pl, mid, k);elsereturn query(tree[u].R, tree[v].R, mid + 1, pr, k - x);
}
int main(){scanf("%d%d", &n, &m);for(int i = 1; i <= n; i++){scanf("%d", &a[i]);b[i] = a[i];}sort(b + 1, b + n + 1);int size = unique(b + 1, b + n + 1) - (b + 1);for(int i = 1; i <= n; i++){int x = lower_bound(b + 1, b + size + 1, a[i]) - b;root[i] = modify(root[i - 1], 1, size, x);}while(m--){int x, y, k;scanf("%d%d%d", &x, &y, &k);printf("%d\n", b[query(root[x - 1], root[y], 1, size, k)]);}return 0;
}