You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
4.0 KiB
C++
118 lines
4.0 KiB
C++
#define _CRT_SECURE_NO_WARNINGS
|
|
#define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING
|
|
#include <bits/stdc++.h>
|
|
using namespace std;
|
|
#define CRP(t, x) const t &x
|
|
#define OPL(t, x) bool operator<(CRP(t, x)) const
|
|
#define FIL(x, v) memset(x, v, sizeof(x))
|
|
#define CLR(x) FIL(x, 0)
|
|
#define NE1(x) FIL(x, -1)
|
|
#define INF(x) FIL(x, 0x3f)
|
|
typedef long long ll, i64;
|
|
const int N = 2e6 + 50, inf = 0x3f3f3f3f;
|
|
int a[N], b[N], idx, rt[N], stub[N << 1];
|
|
struct node
|
|
{
|
|
int ch[2], sz;
|
|
} T[N * 21];
|
|
void insert(int y, int &x, int l, int r, int p)
|
|
{
|
|
T[x = ++idx] = T[y];
|
|
T[x].sz++;
|
|
if (l == r - 1) return;
|
|
int m = (l + r) >> 1;
|
|
p < m ?
|
|
insert(T[y].ch[0], T[x].ch[0], l, m, p) :
|
|
insert(T[y].ch[1], T[x].ch[1], m, r, p);
|
|
}
|
|
int query(int nl, int nr, int l, int r, int k)
|
|
{
|
|
if (l == r - 1) return l;
|
|
int d = T[T[nr].ch[0]].sz - T[T[nl].ch[0]].sz, m = (l + r) >> 1;
|
|
return d > k ?
|
|
query(T[nl].ch[0], T[nr].ch[0], l, m, k) :
|
|
query(T[nl].ch[1], T[nr].ch[1], m, r, k - d);
|
|
}
|
|
int rnk(int nl, int nr, int l, int r, int v)
|
|
{
|
|
if (l == r - 1) return 0;
|
|
int m = (l + r) >> 1;
|
|
return v < m ? rnk(T[nl].ch[0], T[nr].ch[0], l, m, v) :
|
|
T[T[nr].ch[0]].sz + rnk(T[nl].ch[1], T[nr].ch[1], m, r, v);
|
|
return 0;
|
|
}
|
|
int main()
|
|
{
|
|
#ifdef _MSC_VER
|
|
freopen(R"(E:\UserData\Desktop\K-th Closest Distance\14162.in)", "r", stdin);
|
|
#endif // _MSC_VER
|
|
/*int q;
|
|
scanf("%d%d", &n, &q);
|
|
for (int i = 1; i <= n; i++) scanf("%d", a + i);
|
|
memcpy(b, a + 1, n << 2);
|
|
std::sort(b, b + n);
|
|
int m = int(std::unique(b, b + n) - b);
|
|
for (int i = 1; i <= n; i++)
|
|
a[i] = int(std::lower_bound(b, b + m, a[i]) - b);
|
|
for (int i = 1; i <= n; i++) insert(rt[i - 1], rt[i], 0, m, a[i]);
|
|
while (q--)
|
|
{
|
|
int l, r, k;
|
|
scanf("%d%d%d", &l, &r, &k);
|
|
printf("%d\n", b[query(rt[l - 1], rt[r], 0, m, k)]);
|
|
}*/
|
|
int Tt, n, m, L, R, P, K, X;
|
|
scanf("%d", &Tt);
|
|
while (Tt--)
|
|
{
|
|
scanf("%d%d", &n, &m);
|
|
CLR(rt), CLR(T), idx = X = 0;
|
|
for (int i = 1; i <= n; i++) scanf("%d", a + i);
|
|
a[++n] = inf;
|
|
memcpy(b, a + 1, sizeof(*a) * n);
|
|
std::sort(b, b + n);
|
|
//int bn = int(std::unique(b, b + n) - b);
|
|
for (int i = 1; i <= n; i++)
|
|
a[i] = lower_bound(b, b + n, a[i]) - b;
|
|
for (int i = 1; i <= n; i++) insert(rt[i - 1], rt[i], 0, n, a[i]);
|
|
/*for (int i = 0; i < n - 1; i++)
|
|
printf("%d ", b[query(rt[0], rt[n], 0, n, i)]);
|
|
putchar('\n');
|
|
for (int i = 1; i < n; i++)
|
|
printf("%d ", rnk(rt[0], rt[n], 0, n, a[i]));
|
|
printf("%d ", rnk(rt[0], rt[n], 0, n, a[n]));
|
|
putchar('\n');*/
|
|
while (m--)
|
|
{
|
|
scanf("%d%d%d%d", &L, &R, &P, &K);
|
|
L ^= X, R ^= X, P ^= X, K ^= X;
|
|
/*
|
|
int ansL = 0, ansR = 1e6, ansM, Lb, Rb;
|
|
while (ansL < ansR - 1)
|
|
{
|
|
ansM = (ansL + ansR) >> 1;
|
|
Lb = rnk(rt[L - 1], rt[R], 0, n, lower_bound(b, b + n, P - ansM) - b);
|
|
Rb = rnk(rt[L - 1], rt[R], 0, n, lower_bound(b, b + n, P + ansM) - b);
|
|
if (Rb - Lb + 1 > K)
|
|
ansR = ansM;
|
|
else
|
|
ansL = ansM;
|
|
}
|
|
X = ansL;
|
|
Lb = rnk(rt[L - 1], rt[R], 0, n, lower_bound(b, b + n, P - X) - b);
|
|
Rb = rnk(rt[L - 1], rt[R], 0, n, lower_bound(b, b + n, P + X) - b);
|
|
if (Rb - Lb + 1 < K) X++;*/
|
|
static int arr[400];
|
|
int cnt = 0;
|
|
int rkP = rnk(rt[L - 1], rt[R], 0, n, lower_bound(b, b + n, P) - b);
|
|
int fr = max(rkP - 169, 0), to = min(rkP + 169, R - L);
|
|
for (int i = fr; i <= to; i++)
|
|
arr[cnt++] = abs(P - b[query(rt[L - 1], rt[R], 0, n, i)]);
|
|
sort(arr, arr + cnt);
|
|
printf("%d\n", X = arr[K - 1]);
|
|
cnt++;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|