传送门
根据题目描述以及最基础的找规律(真的很基础),答案就是
其实问题的核心就在于求解
所以我们有
考虑如何计算 f(x) f ( x )
找到 1⋯n 1 ⋯ n 及 1⋯m 1 ⋯ m 中所有能整除 x x 的数组成的数对, 答案就是
举个例子,令 n=7,m=8,x=2 n = 7 , m = 8 , x = 2 ,满足 x|i x | i 且 x|j x | j 的数对 (i,j) ( i , j ) 有:
而且观察到 f(4)=2,f(6)=1 f ( 4 ) = 2 , f ( 6 ) = 1 。
这样我们就可以这样计算 f(x) f ( x )
写个伪代码吧
\renewcommand{\tab}[1]{\hskip{#1 em}\hskip{#1 em}}
\renewcommand{\func}{\text}
\renewcommand{\for}{\textbf{for} ~~}
\renewcommand{\to}{~~ \textbf{to} ~~}
\renewcommand{\downto}{~~ \textbf{downto} ~~}
\renewcommand{\return}{\textbf{return} ~~}
\renewcommand{\div}{~~ \textbf{div} ~~}
\renewcommand{\type}[1]{\textbf {#1} ~}
\begin{aligned}
& \tab{0} \func{Solve}(\type{int} n, \type{int} m) \\
& \tab{1} ans \leftarrow 0 \\
& \tab{1} t \leftarrow \min \{n, m\} \\
& \tab{1} \for s \leftarrow t \downto 1 \\
& \tab{2} f[s] \leftarrow (n \div s) \times (m \div s) \\
& \tab{2} \for i \leftarrow 2 \to t \div s \\
& \tab{3} f[s] \leftarrow f[s] - f[i \times s] \\
& \tab{2} ans \leftarrow ans + f[s] \times s \\
& \tab{1} \return ans
\end{aligned}
#include
#include
#include
#include
#define min(x, y) ((x) < (y) ? (x) : (y))
long long f[100005];
int main() {
long long n, m, ans = 0;
scanf("%lld%lld", &n, &m);
long long t = min(n, m);
for (long long s = t; s >= 1; s--) {
f[s] = (n / s) * (m / s);
for (long long i = 2; i * s <= t; i++)
f[s] -= f[i * s];
}
for (long long i = 1; i <= t; i++)
ans += f[i] * i;
printf("%lld\n", 2 * ans - n * m);
return 0;
}