P10532 [XJTUPC2024] 筛法 题解

打表可知答案为 \(n^2\)

一种几何证明,方法来自于讲评。

考虑把 \(n^2\) 个整点放到坐标系中,满足 \((x, y)(x \le n, y \le n)\)

现在从原点向每个满足 \((x, y)(x \perp y)\) 的点引出一条射线,显然每个点都会唯一的被一条射线覆盖到,因为 \((\dfrac{x}{\gcd(x, y)}, \dfrac{y}{\gcd(x, y)})\) 被射线经过,而二者又在一条直线上。

对于每个引出射线的 \((x, y)(x \perp y)\),考虑这条线覆盖的点数,发现恰好就是 \(\left \lfloor \dfrac{n}{\max(i, j)} \right \rfloor\),因为当 \(k > \left \lfloor \dfrac{n}{\max(i, j)} \right \rfloor\) 时,\((xk, yk)\) 必然其一大于 \(n\)

\(\displaystyle\sum\limits_{i=1}^n\sum\limits_{j=1}^n\lfloor \dfrac{n}{\max(i,j)}\rfloor [i \perp j]\) 可以理解为,引出的若干条射线所覆盖到的点数,因为点数为 \(n^2\),所以答案也为 \(n^2\)

// 如果命运对你缄默, 那就活给他看。
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast", "inline", "-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; 
// #define int LL
signed main() {
	// freopen(".in", "r", stdin);
	// freopen(".out", "w", stdout);
	ios :: sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int n;
	cin >> n;
	cout << 1LL * n * n << '\n';
	return 0;
}
posted @ 2024-10-19 16:16  Rainsheep  阅读(34)  评论(0编辑  收藏  举报