题目链接
在一片广袤无垠的原野上,散落着 N N N块磁石。
每个磁石的性质可以用一个五元组 ( x , y , m , p , r ) (x,y,m,p,r) (x,y,m,p,r)描述,其中 x , y x,y x,y表示其坐标, m m m是磁石的质量, p p p是磁力, r r r是吸引半径。
若磁石 A A A与磁石 B B B的距离不大于磁石 A A A的吸引半径,并且磁石 B B B的质量不大于磁石 A A A的磁力,那么 A A A可以吸引 B B B。
小取酒带着一块自己的磁石 L L L来到了这片原野的 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)处,我们可以视磁石 L L L的坐标为 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)。
小取酒手持磁石 L L L并保持原地不动,所有可以被 L L L吸引的磁石将会被吸引过来。
在每个时刻,他可以选择更换任意一块自己已经获得的磁石(当然也可以是自己最初携带的 L L L磁石)在 ( x 0 , y 0 ) (x0,y0) (x0,y0)处吸引更多的磁石。
小取酒想知道,他最多能获得多少块磁石呢?
输入格式
第一行五个整数 x 0 , y 0 , p L , r L , N x_0,y_0,p_L,r_L,N x0,y0,pL,rL,N,表示小取酒所在的位置,磁石L磁力、吸引半径和原野上散落磁石的个数。
接下来 N N N行每行五个整数 x , y , m , p , r x,y,m,p,r x,y,m,p,r,描述一块磁石的性质。
输出格式
输出一个整数,表示最多可以获得的散落磁石个数(不包含最初携带的磁石L)。
数据范围
1 ≤ N ≤ 250000 1≤N≤250000 1≤N≤250000,
− 1 0 9 ≤ x , y ≤ 1 0 9 −10^9≤x,y≤10 ^9 −109≤x,y≤109,
1 ≤ m , p , r ≤ 1 0 9 1≤m,p,r≤10^9 1≤m,p,r≤109
输入样例:
0 0 5 10 5
5 4 7 11 5
-7 1 4 7 8
0 2 13 5 6
2 -3 9 3 4
13 5 1 9 9
输出样例:
3
先将数据按 m m m由小到大排序,分为 n \sqrt n n块,然后对于每块内按到 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)的距离 d d d由小到大排序,这样对于获得的每个磁力块,在 p p p大于等于 m m a x m_{max} mmax的块内扫描,对于第一个 p p p小于 m m a x m_{max} mmax的块遍历,最终时间复杂度为 O ( n n ) O(n\sqrt n) O(nn)。
#include<bits/stdc++.h>#define pi(a) printf("%d\n",a)
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define ll long long
#define fi first
#define se secondusing namespace std;inline int qr() {int f = 0, fu = 1;char c = getchar();while (c < '0' || c > '9') {if (c == '-')fu = -1;c = getchar();}while (c >= '0' && c <= '9') {f = (f << 3) + (f << 1) + c - 48;c = getchar();}return f * fu;
}const int N = 250010;
struct sta {int m, p;ll r, d;
} a[N];inline bool cmpd(sta x, sta y) {return x.d < y.d;
}inline bool cmpm(sta x, sta y) {return x.m < y.m;
}struct BLOCK {int L[N], R[N], pos[N], P[N], mx[N];int n, t, len;bool v[N];inline void build(int _n, int _len) {int now = 0;n = _n, len = _len, t = 0;sort(a + 1, a + 1 + n, cmpm);while (now + len <= n)L[++t] = now + 1, R[t] = now + len, P[t] = now, now += len;if (now < n)L[++t] = now + 1, R[t] = n, P[t] = now;for (int i = 1; i <= t; i++) {for (int j = L[i]; j <= R[i]; j++)pos[j] = i;mx[i] = a[R[i]].m;sort(a + L[i], a + R[i] + 1, cmpd);}}inline int work(int p, ll r, queue<pair<int, ll>> &q) {int res = 0;for (int i = 1; i <= t; i++) {if (p >= mx[i])while (P[i] + 1 <= R[i] && a[P[i] + 1].d <= r) {P[i]++;if (!v[P[i]])q.push({a[P[i]].p, a[P[i]].r}), res++;}else {repi(j, P[i] + 1, R[i])if (!v[j] && a[j].m <= p && a[j].d <= r)q.push({a[j].p, a[j].r}), v[j] = true, res++;break;}}return res;}
} B;int x, y, p, n;
ll r;
queue<pair<int, ll>> q;int main() {x = qr(), y = qr(), p = qr(), r = qr(), n = qr();repi(i, 1, n) {int _x = qr(), _y = qr();a[i].d = 1ll * (x - _x) * (x - _x) + 1ll * (y - _y) * (y - _y);a[i].m = qr(), a[i].p = qr();ll _r = qr();a[i].r = _r * _r;}B.build(n, sqrt(n));q.push({p, 1ll * r * r});int ans = 0;while (!q.empty()) {auto t = q.front();q.pop();ans += B.work(t.fi, t.se, q);}pi(ans);return 0;
}