题解:CF2074D Counting Points

Problem

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;
}
posted @ 2025-03-12 10:28  xAlec  阅读(259)  评论(0)    收藏  举报