2019HDU multi-school fourth K-th Closest Distance - Chairman of the binary tree &&

The meaning of problems

The number given to the $ n $, $ q $ Then there is time to ask, ask each of $ l, r, p, k $ exclusive to one or the answer, is the real value (that is, by force). Each query, output $ [l, r] $ of small $ k $ $ | pa [i] | $.

analysis

Chairman of the tree is usually used to find large sections of the K, in fact, its practical effect is to count the number of values ​​within a certain range. and so,

For each inquiry, half of the answers for possible answers $ x $, to $ R_l \ sim R_r $ the tree line to find $ [px, p + x] $ whether the $ k $.

Chairman tree built on values, this problem of data ranging from $ 10 ^ 6 $, no discrete ( words by force of discrete I will not )

Feeling some cards often, 32 times, 55 times the space are TLE, changed to 64 times over (why ah)

#include <bits / STDC ++ H.>
 the using  namespace STD; 

const  int MAXN 1E5 + = 100 ;
 int n-, m;
 // int A [MAXN];
 // int RT [MAXN], LC [<< MAXN. 5], rc [MAXN << 5], SUM [MAXN << 5];   // RT: different versions of the root node lc / rc: son left and right son (public) sum: and (public) 
int RT [MAXN], LC [MAXN * 64 ], RC [MAXN * 64 ], SUM [MAXN * 64 ];
 int node_cnt;     // Node total count, pnt_disc: a digital value corresponding to the B 
int range = 1000000 ;   // data range, segment tree is the size of the 

void Build ( int& last_node, int l, int r)
{
    last_node = ++ node_cnt;
    sum[last_node] = 0;
    if(l == r)  return;
    int mid = (l + r) >> 1;
    build(lc[last_node], l, mid);
    build(rc[last_node], mid+1, r);
}


int modify(int pre_rt, int v, int l, int r)
{
    int new_rt = ++node_cnt;
    lc[new_rt] = lc[pre_rt];
    rc[new_rt] = rc[pre_rt];
    sum[new_rt] = sum[pre_rt] + 1;

    int mid = (l + r) >> 1;
    if(l == r)  return new_rt;
    if(mid >= v)  lc[new_rt] = modify(lc[new_rt],v, l, mid);
    else  rc[new_rt] = modify(rc[new_rt], v, mid+1, r);
    return new_rt;
}

//查询[ql, qr]中不同元素个数
int query(int rt1, int rt2, int ql, int qr, int l, int r)
{
    //printf("rt1:%d  rt2:%d  k:%d  l:%d  r:%d  ", rt1, rt2, k, l, r);
    if(ql <= l && r <= qr)  return sum[rt2]-sum[rt1];

    int mid = (l + r) >> 1;
    int ans = 0;
    if(ql <= mid)  ans += query(lc[rt1], lc[rt2], ql, qr, l, mid);
    if(qr > mid) ans += query(rc[rt1], rc[rt2], ql, qr, mid+1, r);
    return ans;
}

void print_debug()
{
    printf("node_cnt: %d\n", node_cnt);
    for(int i = 0;i <= node_cnt;i++)
        printf("%d  lc:%d  rc:%d  sum:%d\n", i, lc[i], rc[i], sum[i]);
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &m);

        node_cnt = 0;
        build(rt[0], 1, range);
        for(int I = . 1 ; I <= n-; I ++ ) 
        { 
            int tmp; 
            Scanf ( " % D " , & tmp); 
            RT [I] = Modify (RT [I- . 1 ], tmp, . 1 , Range);   // only modified on the basis of a version of the 
        } 

        int ANS = 0 ;
         for ( int I = 0 ; I <m; I ++ ) 
        { 
            int L, R & lt, P, K; 
            Scanf ( " % D% D% D% D " , & L, R & lt &, & P, & K); 
            L^= ans; r ^= ans;
            p ^= ans; k ^= ans;
            if(l > r)  swap(l, r);

            int L = 0, R = range;      //
            while(L <= R)
            {
                int M = L + (R-L)/2;
                if(query(rt[l-1], rt[r], max(1, p-M), min(p+M, range), 1, range) >= k)
                {
                    ans = M;
                    R = M-1;
                }
                else  L = M+1;
            }
            printf("%d\n", ans);
        }
    }
}
[ Copy to Clipboard ]    [ Save to File]

 

 

Reference links:

1. https://blog.csdn.net/birdmanqin/article/details/97964662

2. http://morecoder.com/article/1254619.html

Guess you like

Origin www.cnblogs.com/lfri/p/11289552.html