码迷,mamicode.com
首页 > 其他好文 > 详细

2019HDU多校 Round4

时间:2019-07-31 23:34:55      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:tmp   while   gif   ret   答案   click   turn   出现   题意   

 

08 K-th Closest Distance

题意:询问区间l,r中与数p的距离为第k大的数 求这个距离

题解:很裸的主席树 二分答案 然后可以用主席数判断在这个区间内 一段值域内出现的数

   之前没写过主席树求 统计小于区间某个数的个数 自作主张写的二分区间k小 loglog tle死

   看了汪聚聚的代码 才明白主席树功能的强大 以后会了

技术图片
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;

int n, m, cnt, len;
int a[MAXN];
int b[MAXN];
int sum[MAXN << 5];
int ls[MAXN << 5];
int rs[MAXN << 5];
int t[MAXN];

int build(int l, int r) {
    int rt = ++cnt;
    int m = l + r >> 1;
    sum[rt] = 0;

    if(l < r) {
        ls[rt] = build(l, m);
        rs[rt] = build(m + 1, r);
    }
    return rt;
}

int add(int o, int l, int r, int k) {
    int rt = ++cnt;
    int m = l + r >> 1;
    ls[rt] = ls[o]; rs[rt] = rs[o]; sum[rt] = sum[o] + 1;

    if(l < r) {
        if(k <= m) ls[rt] = add(ls[o], l, m, k);
        else rs[rt] = add(rs[o], m + 1, r, k);
    }
    return rt;
}

int query(int x, int y, int l, int r, int ql, int qr) {
    if(ql <= l && qr >= r) return sum[y] - sum[x];

    int res = 0;
    int m = l + r >> 1;
    if(ql <= m) res += query(ls[x], ls[y], l, m, ql, qr);
    if(qr > m) res += query(rs[x], rs[y], m + 1, r, ql, qr);
    return res;
}

bool check(int ql, int qr, int x, int y, int k) {
    int t1 = lower_bound(b + 1, b + 1 + len, ql) - b;
    int t2 = lower_bound(b + 1, b + 1 + len, qr + 1) - b - 1;

    if(t1 > t2 || t2 > len || t1 > len) return 0;
    int tmp = query(t[x - 1], t[y], 1, len, t1, t2);
    if(tmp >= k) return 1;
    else return 0;
}

int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &n, &m);
        cnt = 0;
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];
        sort(b + 1, b + 1 + n);
        len = unique(b + 1, b + 1 + n) - b - 1;

        t[0] = build(1, len);
        for(int i = 1; i <= n; i++) {
            int tt = lower_bound(b + 1, b + 1 + len, a[i]) - b;
            t[i] = add(t[i - 1], 1, len, tt);
        }

        int x = 0;
        for(int i = 1; i <= m; i++) {
            int l, r, p, k;
            scanf("%d%d%d%d", &l, &r, &p, &k);
            l ^= x, r ^= x, p ^= x, k ^= x;

            int l1 = 0, r1 = 1e6;
            int mid = l1 + r1 >> 1;
            while(l1 + 1 < r1) {
                mid = l1 + r1 >> 1;
                if(check(p - mid, p + mid, l, r, k)) r1 = mid;
                else l1 = mid;
            }
            if(check(p - l1, p + l1, l, r, k)) x = l1;
            else x = r1;
            printf("%d\n", x);
        }
    }
    return 0;
}
K-th Closest Distance

 

2019HDU多校 Round4

标签:tmp   while   gif   ret   答案   click   turn   出现   题意   

原文地址:https://www.cnblogs.com/lwqq3/p/11279827.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!