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 }
  • 相关阅读:
    [JSOI2007][BZOJ1031] 字符加密Cipher|后缀数组
    leetcode Flatten Binary Tree to Linked List
    leetcode Pascal's Triangle
    leetcode Triangle
    leetcode Valid Palindrome
    leetcode Word Ladder
    leetcode Longest Consecutive Sequence
    leetcode Sum Root to Leaf Numbers
    leetcode Clone Graph
    leetcode Evaluate Reverse Polish Notation
  • 原文地址:https://www.cnblogs.com/sainsist/p/11350015.html
Copyright © 2011-2022 走看看