zoukankan      html  css  js  c++  java
  • [2019杭电多校第四场][hdu6621]K-th Closest Distance(主席树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6621

    题意为求区间[l,r]内第k小|a[i]-p|的值。

    可以二分答案,如果二分的值为x,则判断区间[l,r]内是否有k个数在[p-x,p+x]范围内。所以就用主席树搞一下。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<vector>
     7 #define lson l, mid, i<<1
     8 #define rson  mid + 1, r, i<<1|1
     9 using namespace std;
    10 typedef long long ll;
    11 const int maxn = 1e6 + 10;
    12 int root[maxn], rs[maxn * 20], ls[maxn * 20], val[maxn * 20];
    13 int cnt;
    14 void update(int k, int l, int r, int &i) {
    15     val[++cnt] = val[i] + 1, ls[cnt] = ls[i], rs[cnt] = rs[i];
    16     i = cnt;
    17     if (l == r)
    18         return;
    19     int mid = l + r >> 1;
    20     if (k <= mid)
    21         update(k, l, mid, ls[i]);
    22     else
    23         update(k, mid + 1, r, rs[i]);
    24 }
    25 int query(int u, int v, int L, int R, int l, int r) {
    26     if (L <= l && r <= R)
    27         return val[u] - val[v];
    28     int mid = l + r >> 1;
    29     int ans = 0;
    30     if (L <= mid)
    31         ans += query(ls[u], ls[v], L, R, l, mid);
    32     if (R > mid)
    33         ans += query(rs[u], rs[v], L, R, mid + 1, r);
    34     return ans;
    35 }
    36 int check(int L, int R, int p, int x) {
    37     int l = max(p - x, 1), r = min(p + x, (int)1e6);
    38     return query(root[R], root[L - 1], l, r, 1, 1e6);
    39 }
    40 int main() {
    41     int t;
    42     scanf("%d", &t);
    43     while (t--) {
    44         int n, m, x, cnt = 0;
    45         scanf("%d%d", &n, &m);
    46         for (int i = 1; i <= n; i++) {
    47             scanf("%d", &x);
    48             root[i] = root[i - 1];
    49             update(x, 1, 1e6, root[i]);
    50         }
    51         int ans = 0, L, R, p, k;
    52         for (int i = 1; i <= m; i++) {
    53             scanf("%d%d%d%d", &L, &R, &p, &k);
    54             L ^= ans, R ^= ans, p ^= ans, k ^= ans;
    55             int l = 0, r = 1e6;
    56             while (l <= r) {
    57                 int mid = l + r >> 1;
    58                 int w = check(L, R, p, mid);
    59                 if (w >= k) {
    60                     r = mid - 1;
    61                     ans = mid;
    62                 }
    63                 else
    64                     l = mid + 1;
    65             }
    66             printf("%d
    ", ans);
    67         }
    68     }
    69 }
  • 相关阅读:
    从尾到头打印链表(基于js)
    替换空格(基于js)
    二维数组的查找(基于js)
    关于document对象
    js之DOM操作总结
    将博客搬至CSDN
    关于js中的数组
    干货集中营
    vim编辑器学习记录
    python3 多线程爆破ftp、mysql、ssh
  • 原文地址:https://www.cnblogs.com/sainsist/p/11350015.html
Copyright © 2011-2022 走看看