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; }