Files
python/TangDou/AcWing_TiGao/T5/RongChi/HDU2841_2.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

90 lines
2.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
// 性能非常棒,但是没看懂,等功能加深后再回来看看。
// 据说这道题,还可以用莫比乌斯反演来做,以后再
// 筛法求欧拉函数
int primes[N]; //保存的是每一个质数
int cnt; // cnt代表质数下标,就是到第几个了
int phi[N]; //欧拉函数值,一般叫Φ,函数名不能是希腊字母,所以转为phi
bool st[N]; //代表是不是已经被筛掉了
LL res; //结果
void get_eulers(int n) {
// 1的欧拉函数值
phi[1] = 1;
//如果当前i没有被筛过,说明当前i是一个质数
for (int i = 2; i <= n; i++) {
if (!st[i]) {
//增加一个质数
primes[cnt++] = i;
phi[i] = i - 1;
}
for (int j = 0; primes[j] <= n / i; j++) {
int t = primes[j] * i;
st[t] = true;
if (i % primes[j] == 0) {
phi[t] = phi[i] * primes[j];
break;
} else
phi[t] = phi[i] * (primes[j] - 1);
}
}
}
int n, m;
int num, p[10], sum, i;
void dfs(int pos, int lcm, int id) {
if (id == 0) {
if (i & 1)
num += (m / lcm);
else
num -= (m / lcm);
return;
}
if (pos > sum) return;
if (lcm * p[pos] <= m)
dfs(pos + 1, lcm * p[pos], id - 1);
dfs(pos + 1, lcm, id);
return;
}
int solve(int k) {
sum = 0;
//下面是分解质数
for (int i = 2; i <= k / i; i++) {
if (k % i == 0) {
p[++sum] = i;
while (k % i == 0) k /= i;
}
}
if (k > 1) p[++sum] = k;
for (i = 1; i <= sum; i++) dfs(1, 1, i);
return m - num;
}
int main() {
//筛法求欧拉函数
get_eulers(N - 10);
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m); // n行m列
if (m > n) swap(n, m);
LL res = 1;
for (int i = 2; i <= m; i++) res += 2 * phi[i]; //这是啥意思呢?
for (int i = m + 1; i <= n; i++) {
num = 0;
res += solve(i);
}
printf("%lld\n", res);
}
return 0;
}