Multi-school 4 K-th Closest Distance Chairman of the tree half the answer

  The meaning of problems: Given a query sequence with m ai Q lrpk the interval distance lr and p (the difference between the absolute value of) the k small

 

When half of the game to find the location lr p in the interval in which the left and right and then traverse the crazy overtime k   

 

Complexity can remove a k 

 

Direct-half answer  

Lr Chairman tree maintenance in the interval [p-mid, p + mid] to the number of

Note that this classic Chairman tree maintenance mode! ! ! ! ! ! Maintenance interval [ai belonging x, y] is the number of

 

 

Chairman of ordinary tree is then thrown into discrete intervals T as subscript

 

This is based on data from small to large order of precedence for the T 

 

 

 

#include <bits/stdc++.h>
using namespace std;

const int N = 110000;
const int M = 2000000;

int nodes;
int b[N], id[N];
int tot, K;

int T[M],lson[M],rson[M],t[M];



inline void up(int x,int l,int r, int pre,int &pos)
{
    pos=++ncnt;
    lson[pos]=lson[pre];
    rson[pos]=rson[pre];
    t[pos]=t[pre]+1;
    if(l==r)return ;int m=l+r>>1;
    if(x<=m)up(x,l,m,lson[pos],lson[pos]);
    else up(x,m+1,r,rson[pos],rson[pos]);
}

void qsum(int L,int R,int x,int y,int l,int r)
{
    if(tot>=K)return ;
    
    if(L<=l&&r<=R)
    {
        tot+=t[y]-t[x];return ;
    }
    int m=l+r>>1;
    if(L<=m)qsum(L,R,lson[x],lson[y],l,m);
    if(R>m)qsum(L,R,rson[x],rson[y],m+1,r);
}
 


int main() {
    int ncase; cin>>ncase;
    while (ncase--) {
        int prv = 0;
        int n, m; scanf("%d%d",&n,&m);
        for (int i = 1; i <= n; i++) scanf("%d",&b[i]), id[i] = i;
        sort(id + 1, id + n + 1, [](int i, int j) { return b[i] < b[j]; });
        sort(b + 1, b + n + 1);
        
        ncnt = 0;
        
        for (int i = 1; i <= n; i++)up(id[i],  1,n,    T[i-1],T[i]);   //root[i] = modify(1, 1, n, id[i], root[i - 1]);
        
        for (int i = 1; i <= m; i++) {
            int L, R, p; 
            scanf("%d%d%d%d",&L,&R,&p,&K);
            L ^= prv, R ^= prv, p ^= prv, K ^= prv;
            
            int st = -1, en = 1e8;
            while (en - st > 1) {
                int mid = st + en >> 1;
                int l = lower_bound(b + 1, b + n + 1, p - mid) - b;
                int r = upper_bound(b + 1, b + n + 1, p + mid) - b - 1;
                tot = 0;
            
                qsum(L,R,T[l-1],T[r],1,n);
                if (tot >= K) en = mid;
                else st = mid;
            }
            prv = en;
            printf("%d\n",en);
        }
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/bxd123/p/11279626.html