• POJ 6621: K-th Closest Distance(主席树 + 二分)


    K-th Closest Distance

    Time Limit: 20000/15000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
    Total Submission(s): 1697    Accepted Submission(s): 633


    Problem Description
    You have an array: a1, a2, �, an and you must answer for some queries.
    For each query, you are given an interval [L, R] and two numbers p and K. Your goal is to find the Kth closest distance between p and aL, aL+1, ..., aR.
    The distance between p and ai is equal to |p - ai|.
    For example:
    A = {31, 2, 5, 45, 4 } and L = 2, R = 5, p = 3, K = 2.
    |p - a2| = 1, |p - a3| = 2, |p - a4| = 42, |p - a5| = 1.
    Sorted distance is {1, 1, 2, 42}. Thus, the 2nd closest distance is 1.
     
    Input
    The first line of the input contains an integer T (1 <= T <= 3) denoting the number of test cases.
    For each test case:
    冘The first line contains two integers n and m (1 <= n, m <= 10^5) denoting the size of array and number of queries.
    The second line contains n space-separated integers a1, a2, ..., an (1 <= ai <= 10^6). Each value of array is unique.
    Each of the next m lines contains four integers L', R', p' and K'.
    From these 4 numbers, you must get a real query L, R, p, K like this: 
    L = L' xor X, R = R' xor X, p = p' xor X, K = K' xor X, where X is just previous answer and at the beginning, X = 0.
    (1 <= L < R <= n, 1 <= p <= 10^6, 1 <= K <= 169, R - L + 1 >= K).
     
    Output
    For each query print a single line containing the Kth closest distance between p and aL, aL+1, ..., aR.
     
    Sample Input
    1 5 2 31 2 5 45 4 1 5 5 1 2 5 3 2
     
    Sample Output
    0 1
     
     
    杭电多校第四场...
    结构:主席树 + 二分
     
    题解:首先按照模板走,创建一颗主席树。然后更具题目意思,我先设ans就是我二分的时候要找到的答案,那么就有 | p - an | = ans, 则有两种情况 p - an = ans , an - p = ans, 那么可以确定 an 的值域 [ p - ans, p + ans ]。
     
    注意:主席树的数组一定要开的够大,不然就会TLE...我开的40倍就TLE了,看大佬的开的55倍,改了一下就过了。
     
    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    const int maxn = 1e5+7;
    const int INF = 1e6+7;
    
    struct node {
        int l, r, s;
    }tree[maxn * 55];   
    
    int root[maxn];
    int arr[maxn];  
    int n, m;
    int cnt;
    
    void update(int l, int r, int pre, int &cur, int pos) {
        cur = ++cnt;
        tree[cur] = tree[pre];
        tree[cur].s++;
        if(l == r) {
            return;
        }
        int mid = (l + r) >> 1;
        if(pos <= mid) {
            update(l, mid, tree[pre].l, tree[cur].l, pos);
        } else {
            update(mid + 1, r, tree[pre].r, tree[cur].r, pos);
        }
    }
    
    int query(int x, int y, int l ,int r, int pre, int cur) {
        if(x <= l && r <= y) {
            return tree[cur].s - tree[pre].s;
        }
        int mid = (l + r) >> 1;
        int res = 0;
        if(x <= mid) {
            res += query(x, y, l ,mid, tree[pre].l, tree[cur].l);
        } 
        if(y > mid) {
            res += query(x, y, mid + 1, r, tree[pre].r, tree[cur].r);
        }
        return res;
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        while(T--) {
            cnt = 0;
            scanf("%d %d", &n, &m);
            for(int i = 1; i <= n; i++) {
                scanf("%d", &arr[i]);
                update(1, INF, root[i - 1], root[i], arr[i]);
            }
            int ans = 0;
            while(m--) {
                int l, r, p, k;
                scanf("%d %d %d %d", &l, &r, &p, &k);
                l = l ^ ans;
                r = r ^ ans;
                p = p ^ ans;
                k = k ^ ans;
                int pl = 0, pr = INF;
                while(pl <= pr) {
                    int mid = (pl + pr) >> 1;
                    if(query(max(1, p - mid), min(INF, p + mid), 1, INF, root[l - 1], root[r]) >= k) {      //此处的max和min是为了防止超出[0, 1e6]的范围
                        ans = mid;
                        pr = mid - 1;
                    } else {
                        pl = mid + 1;
                    }
                }
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
     
  • 相关阅读:
    vs2010配置驱动开发
    寒假训练 npuctf_2020_bad_guy(11/250)利用overlap与fastbin attack来篡改fd指针,从而通过stdout达到泄露libc
    寒假训练 [OGeek2019]bookmanager(10/250)
    寒假训练 npuctf_2020_level2(9/250)将heap分配到bss上,从而满足程序条件
    寒假训练 npuctf_2020_level2(8/250)修改ebp链来间接修改返回地址
    Windows XP源码跟踪
    寒假训练 houseoforange_hitcon_2016(7/250)
    寒假训练 jarvisoj_level6_x64(6/250)
    寒假训练 de1ctf_2019_weapon(5/250)
    glibc源码逆向——fwrite函数
  • 原文地址:https://www.cnblogs.com/buhuiflydepig/p/11281416.html
Copyright © 2020-2023  润新知