Example: https://www.luogu.org/problemnew/show/P3834
Chairman of the tree is used to query each historical version.
The problem code is as follows
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=200001; int n,m,tot; ll a[maxn],b[maxn]; struct stree{ int lc,rc; ll sum; #define lc(x) tree[x].lc #define rc(x) tree[x].rc #define s(x) tree[x].sum }tree[maxn<<5]; int root[maxn]; inline int build(int l,int r){ int p=++tot; if(l==r) return p; int mid=(l+r)>>1; lc(p)=build(l,mid); rc(p)=build(mid+1,r); return p; } inline int insert(int now,int l,int r,int x){ int p=++tot; tree[p]=tree[now]; s(p)++; if(l==r)return p; int mid=(l+r)>>1; IF (X <= MID) LC (P) = INSERT (LC (now), L, MID, X); the else RC (P) = INSERT (RC (now), MID + . 1 , R & lt, X); return P; } inline int ASK ( int P, int Q, int L, int R & lt, int K) { // on p, q time two nodes, number of values in the range [l, r] of the IF (L R & lt ==) return L; int MID = (L + R & lt) >> . 1 ; int LCNT S = (LC (Q)) - S (LC (P)); IF (K <= LCNT) return ASK (LC ( P), LC (Q), L, MID, K); // Find the left son two nodes. else return ask(rc(p),rc(q),mid+1,r,k-lcnt); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a[i]),b[i]=a[i]; sort(b+1,b+n+1); int cnt=unique(b+1,b+n+1)-b-1; root[0]=build(1,cnt); for(int i=1;i<=n;i++){ a[i]=lower_bound(b+1,b+cnt+1,a[i])-b; root[i]=insert(root[i-1],1,cnt,a[i]); } while(m--){ int l,r,k; scanf("%d%d%d",&l,&r,&k); printf("%lld\n",b[ask(root[l-1],root[r],1,cnt,k)]); } system("pause"); return 0; }
Historical version of this title is inserted before the i-th number.
The number of elements [l, r] value range.