[Template] [] [tree] data structure Chairman tree

Skills I: Discrete deduplication

for ( int I = . 1 ; I <= n-; I ++) Scanf ( " % D " , & A [I]), B [I] = A [I]; 
    Sort (B + . 1 , B + n-+ . 1 );
     int UNIQUE = nn (B + . 1 , B + n-+ . 1 )-b- . 1 ; // assume that the number of x, then the pointer will stop nn x + 1 at the position of the first number, nn and later are repeated elements for ( int I = . 1 ; I <= n-; I ++ ) 
        ID [I] = lower_bound (B + . 1 , B + NN + . 1 , a [I]) - B; after the new discrete value //

Skills II: can persistent data structure

Modify affected part, then a pointer to the new points, recording a new point can be easily searched

void updata(int l,int r,int &nw,int pre,int x)
{
    nw=++cnt;
    t[nw]=t[pre];t[nw].sum ++;
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(mid>=x) updata(l,mid,t[nw].lc ,t[pre].lc ,x);
    else updata(mid+1,r,t[nw].rc ,t[pre].rc ,x);
}

Skills III: Range of ships can be disassembled into a [R] -a [L-1]

Even though each has a branch N

int query(int l,int r,int ll,int rr,int kk)
{
    if(l==r) return l;
    int s=t[t[rr].lc ].sum -t[t[ll].lc ].sum ;
    int mid=(l+r)>>1;
    if(s>=kk) return query(l,mid,t[ll].lc ,t[rr].lc ,kk);
    else return query(mid+1,r,t[ll].rc ,t[rr].rc ,kk-s);
}

Finally: Chairman tree template

//luogu P3834 
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,m;
const int N=200003;
int a[N],b[N],id[N];

struct node
{
    int sum,lc,rc;
}t[N*40];
int cnt,rt[N];
int build(int l,int r)
{
    int rt=++cnt;
    t[rt].sum =0;
    if(l!=r)
    {
        int mid=(l+r)>>1;
        t[rt].lc =build(l,mid);
        t[rt].rc =build(mid+1,r);
    }
    return rt;
}
void updata(int l,int r,int &nw,int pre,int x)
{
    nw=++cnt;
    t[nw]=t[pre];t[nw].sum ++;
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(mid>=x) updata(l,mid,t[nw].lc ,t[pre].lc ,x);
    else updata(mid+1,r,t[nw].rc ,t[pre].rc ,x);
}

int query(int l,int r,int ll,int rr,int kk)
{
    if(l==r) return l;
    int s=t[t[rr].lc ].sum -t[t[ll].lc ].sum ;
    int mid=(l+r)>>1;
    if(s>=kk) return query(l,mid,t[ll].lc ,t[rr].lc ,kk);
    else return query(mid+1,r,t[ll].rc ,t[rr].rc ,kk-s);
}

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 nn = UNIQUE (B + . 1 , B + n-+ . 1 )-b- . 1 ; // assume that the number of x, then the pointer will stop nn in the first position of the number x + 1 
     // to weight discrete 
    RT [ 0 ] = Build ( . 1 , NN);
     for ( int I = . 1; I <= n-; I ++ ) 
    { 
        ID [I] = lower_bound (B + . 1 , B + NN + . 1 , A [I]) - B; 
        UPDATA ( . 1 , NN, RT [I], RT [I- . 1 ], ID [I]); // needs to count to a serial array of discrete 
    } // new value after the discrete 
    int X, Y, K;
     the while (M-- ) 
    { 
        Scanf ( " % D% D% D " , & X, & Y, & K); 
        the printf ( " % D \ n- " , b [Query ( . 1 , NN, RT [X- . 1 ], RT [Y], K)]); // a serial number to b array discrete 
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/xwww666666/p/11270249.html