题目
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;
//分别为根节点,左儿子,有儿子,每个区间的个数,编号<