2019杭电多校第三场 1008 K-th Closest Distance
Posted inctry
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019杭电多校第三场 1008 K-th Closest Distance相关的知识,希望对你有一定的参考价值。
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6621
考虑主席树,我们先将所有值离散化之后建主席树。对于每个查询\(s,t,p,k\)
我们考虑二分一个值\(mid\),考虑当前区间内,\([p-mid, p+mid]\)的值有多少个,很显然这是符合单调性的,那么我们只需要每次判断即可。时间复杂度\(O(nlog^2n)\)
#include <bits/stdc++.h>
#define pii pair<int, int>
#define pil pair<int, long long>
#define pll pair<long long, long long>
#define lowbit(x) ((x)&(-x))
#define mem(i, a) memset(i, a, sizeof(i))
#define sqr(x) ((x)*(x))
#define all(x) x.begin(),x.end()
#define ls (k << 1)
#define rs (k << 1 | 1)
using namespace std;
typedef long long ll;
template <typename T>
inline void read(T &X)
X = 0; char ch = 0; T op = 1;
for(; ch > '9' || ch < '0'; ch = getchar())
if(ch == '-') op = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar())
X = (X << 3) + (X << 1) + ch - 48;
X *= op;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 5;
int T[N << 5],L[N << 5],R[N << 5],sum[N << 5];
int n,m,cnt;
int a[N],id[N];
int update(int pre, int l, int r, int x)
int rt = ++cnt;
L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = sum[pre] + 1;
//cout << rt << " " << sum[rt] << "\n";
int mid = l + r >> 1;
if(l < r)
if(x <= mid) L[rt] = update(L[pre], l, mid, x);
else R[rt] = update(R[pre], mid + 1, r, x);
return rt;
int query(int u, int v, int l, int r, int s, int t)
int x = sum[v] - sum[u];
// cout << l << " " << r << " " << s << " " << t << " " << L[v] << " " << R[v] << "\n";
int ans = 0;
if(s <= l && t >= r)
return x;
int mid = l + r >> 1;
if(s <= mid) ans += query(L[u], L[v], l, mid, s, t);
if(t > mid) ans += query(R[u], R[v], mid + 1, r, s, t);
return ans;
int main()
#ifdef INCTRY
freopen("input.txt", "rt", stdin);
#endif
int t;
cin >> t;
while(t--)
read(n); read(m); cnt = 0;
vector<int> v;
for(int i = 1; i <= n; i++)
read(a[i]);
v.push_back(a[i]);
sort(all(v)); v.erase(unique(all(v)), v.end());
for(int i = 1; i <= n; i++)
id[i] = lower_bound(all(v), a[i]) - v.begin() + 1;
int nall = v.size();
T[0] = 0;
for(int i = 1; i <= n; i++)
T[i] = update(T[i - 1], 1, nall, id[i]);
//cout << n << " " << m <<"\n";
int prv = 0;
int ans;
//cout << T[5] << " " << L[T[5]] << " " << R[T[5]] << "\n";
//cout << query(T[0], T[5], 1, nall, 1, 4);
for(int i = 1; i <= m; i++)
int s,t,p,k;
//cout << i << " " << m << "\n";
read(s); read(t); read(p); read(k);
s ^= prv; t ^= prv; p ^= prv; k ^= prv;
int l = 0, r = 1e8;
while(l <= r)
int mid = l + r >> 1;
int p1 = lower_bound(all(v), p - mid) - v.begin() + 1;
int p2 = upper_bound(all(v), p + mid) - v.begin();
//cout << p1 << " " << p2 << " " << p - mid << " " << p + mid << " ";
int tot = query(T[s-1], T[t], 1, nall, p1, p2); //cout << tot <<"\n";
if(tot >= k) ans = mid, r = mid - 1;
else l = mid + 1;
cout << ans << "\n";
prv = ans;
#ifdef INCTRY
cerr << "\nTime elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
以上是关于2019杭电多校第三场 1008 K-th Closest Distance的主要内容,如果未能解决你的问题,请参考以下文章
2019杭电多校第三场 1004 Distribution of books