K-th Closest Distance(HDU - 6621)

题目

You have an array: a1, a2, , an and you must answer for some queries.
For each query, you are given an interval [L, R] and two numbers p and K. Your goal is to find the Kth closest distance between p and aL, aL+1, …, aR.
The distance between p and ai is equal to |p - ai|.
For example:
A = {31, 2, 5, 45, 4 } and L = 2, R = 5, p = 3, K = 2.
|p - a2| = 1, |p - a3| = 2, |p - a4| = 42, |p - a5| = 1.
Sorted distance is {1, 1, 2, 42}. Thus, the 2nd closest distance is 1.

Input
The first line of the input contains an integer T (1 <= T <= 3) denoting the number of test cases.
For each test case:
The first line contains two integers n and m (1 <= n, m <= 10^5) denoting the size of array and number of queries.
The second line contains n space-separated integers a1, a2, …, an (1 <= ai <= 10^6). Each value of array is unique.
Each of the next m lines contains four integers L’, R’, p’ and K’.
From these 4 numbers, you must get a real query L, R, p, K like this:
L = L’ xor X, R = R’ xor X, p = p’ xor X, K = K’ xor X, where X is just previous answer and at the beginning, X = 0.
(1 <= L < R <= n, 1 <= p <= 10^6, 1 <= K <= 169, R - L + 1 >= K).

Output
For each query print a single line containing the Kth closest distance between p and aL, aL+1, …, aR.

Sample Input
1
5 2
31 2 5 45 4
1 5 5 1
2 5 3 2

Sample Output
0
1

思路:
这个题目涉及到区间第k大,首先肯定想到是主席树,关键在于这个绝对值对其影响,倘若只是按照给了数量建立二叉树,加上本题是强制在线,那么肯定行不通(因为你的排序会出错),
那么我们换个思路,建立一颗1-1e6大小的主席树,每个叶子记录一个一个数,这样的话,最开始建立的一颗主席树就可以一直用下去,对于绝对值,相当于在一个叶子节点左边和右边查询,我们用二分来找叶子节点,然后判断区间我们每次二分答案,二分的上下限是[0,sz],sz是序列中最大的数字。每次查询该区间内大小在[p−mid,p+mid]范围内的数字个数,它们到达p的距离均小于等于mid,如果多于k,说明范围要更小,如果少于k,说明范围要更大,如果等于k,也说明范围要缩小,因为我们要找到精确的范围。就这样二分,得到答案……

代码如下:(。・∀・)ノ

#include<bits/stdc++.h>
using namespace std;
const int mx=1e5+10,N=1e6;
int rt[mx],ls[mx*22],rs[mx*22],sum[mx*22],cnt;
  //分别为根节点,左儿子,有儿子,每个区间的个数,编号<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值