2019 杭电多校 HDU - 6621 K-th Closest Distance 主席树+二分

题意:n个数,q次查询,查询[l , r] 内, | a[i] - p | 第k大的数。

思路:主席树维护权值,要求|a[i]-p|的第k大,可以二分答案,若区间[l,r]内的数在范围[p-ans,p+ans]的数等于k,则ans就是答案,所以二分答案求出来,复杂度O(q*log(m)*log(m))。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, M, a[N], cnt, root[N], t;
struct node {
    int l, r, sum;
} zxs[N * 40];
void add(int l, int r, int pre, int &now, int pos) {
    zxs[++cnt] = zxs[pre], now = cnt, zxs[cnt].sum++;
    if(l == r)
        return;
    int m = (l + r) >> 1;
    if(pos <= m)
        add(l, m, zxs[pre].l, zxs[now].l, pos);
    else
        add(m + 1, r, zxs[pre].r, zxs[now].r, pos);
}
int query(int pl, int pr, int l, int r, int L, int R) {
    if(pl <= l && r <= pr)
        return zxs[R].sum - zxs[L].sum;
    int m = (l + r) >> 1, ans = 0;
    if(pl <= m)
        ans += query(pl, pr, l, m, zxs[L].l, zxs[R].l);
    if(pr > m)
        ans += query(pl, pr, m + 1, r, zxs[L].r, zxs[R].r);
    return ans;
}
int main() {
    freopen("14162.in","r",stdin);
    freopen("14162.out","w",stdout);
    scanf("%d", &t);
    while(t--) {
        cnt = 0;
        memset(root, 0, sizeof root);
        scanf("%d %d", &n, &M);
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]), add(1, N, root[i - 1], root[i], a[i]);
        int x = 0;
        while(M--) {
            int l, r, p, k, pl = 0, pr = N;
            scanf("%d %d %d %d", &l, &r, &p, &k);
            l = (l ^ x), r = (r ^ x), p = (p ^ x), k = (k ^ x);
            while(pl <= pr) {
                int m = (pl + pr) >> 1;
                if(query(max(1, p - m), min(N, p + m), 1, N, root[l - 1], root[r]) >= k) {
                    x = m;
                    pr = m - 1;
                } else
                    pl = m + 1;
            }
            printf("%d\n", x);
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值