[] Chairman weight code tree data structure (segment tree may be persistent)

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.

Guess you like

Origin www.cnblogs.com/ChrisKKK/p/11025298.html