zoukankan      html  css  js  c++  java
  • 2019HDU多校 Round4

    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
    ", x);
            }
        }
        return 0;
    }
    K-th Closest Distance
  • 相关阅读:
    图像处理基础2
    c++之morphologyEx(形态学操作)
    图像处理基础
    Mac 安装QT
    Qmake VS Cmake
    g++,qmake,cmake区别
    C++11中的匿名函数(lambda函数,lambda表达式)
    c++相关要点
    spritekit基础节点学习
    spriteKit简单学习
  • 原文地址:https://www.cnblogs.com/lwqq3/p/11279827.html
Copyright © 2011-2022 走看看