题解:CF2074D Counting Points
Statement
给定 \(n\) 个圆心在 \(x\) 轴上圆和其半径,求包含在所有圆中整数点的个数。
即为求满足 \((x_i - x)^2 + y^2 \leq r_i^2\) 的 \((x,y)\) 的个数。
Solution
\[y^2 \leq r_i^2 - (x_i - x)^2
\\ \downarrow \\
-\sqrt{r_i^2 - (x_i - x)^2} \leq y \leq \sqrt{r_i^2 - (x_i - x)^2}
\]
记 \(k = \lfloor{\sqrt{r_i^2 - (x_i - x)^2}}\rfloor\),\(y\) 在这个范围内有 \(2k + 1\) 个取值可能,这样就可以用 map 维护然后统计答案。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 2e5 + 10;
int Test, n, m;
struct Point {
int x, r;
bool operator < (const Point &s) const { return r - x < s.r - s.x; }
} P[MAXN];
map<int, int> Pos;
inline int sqr (int x) { return x * x; }
inline int getPos (Point s, int x) { return sqrt (sqr (s.r) - sqr (s.x - x)); }
inline void Solve() {
cin >> n >> m, Pos.clear();;
for (int i = 1; i <= n; i ++) cin >> P[i].x;
for (int i = 1; i <= n; i ++) cin >> P[i].r;
sort (P + 1, P + n + 1);
for (int i = 1; i <= n; i ++) {
for (int p = P[i].x - P[i].r; p <= P[i].x + P[i].r; p ++)
Pos[p] = max (Pos[p], getPos (P[i], p));
}
int Ans = 0;
for (map<int,int>::iterator iter = Pos.begin(); iter != Pos.end(); iter ++) {
int x = iter -> second;
Ans += (x * 2 + 1);
}
cout << Ans << endl;
}
signed main() {
cin >> Test;
while (Test --) Solve();
return 0;
}

浙公网安备 33010602011771号