HDU5663 Hillan and the girl
题意
求
\[\sum_{i=1}^{n}\sum_{j=1}^m[gcd(i,j)为完全平方数]
\]
题解
我们设一个函数\(f(x)\)表示
\[f(x)=
\begin{cases}
1(x为完全平方数)\\
0(x不为完全平方数)
\end{cases}
\]
然后大力推式子,最后推出来是这样的
\[\sum_{T=1}^{n}\frac{n}{T}\frac{m}{T}\sum_{k|T}\mu(\frac{T}{k})f(k)
\]
后面那段并不是积性函数。。。但是会发现完全平方数其实很少。所以可以枚举完全平方数,大力埃筛\(O(\sqrt{n}log(\sqrt{n}))\)预处理。复杂度很稳。
然后询问就可以\(O(T\sqrt{n})\)回答了。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e7 + 10;
#define ll long long
int mu[N], T, p[N], cnt;
ll F[N];
bool vis[N];
ll n, m;
void init() {
mu[1] = 1;
for(int i = 2; i < N; ++i) {
if(!vis[i]) p[++cnt] = i, mu[i] = -1;
for(int j = 1; j <= cnt && i * p[j] < N; ++j) {
vis[i * p[j]] = 1;
if(i % p[j] == 0) break;
mu[i * p[j]] = -mu[i];
}
}
for(int i = 1; i * i < N; ++i)
for(int j = i * i; j < N; j += i * i)
F[j] += mu[j / (i * i)];
for(int i = 1; i < N; ++i) F[i] += F[i - 1];
}
ll calc(ll n, ll m) {
ll ans = 0;
if(n > m) swap(n, m);
for(ll l = 1, r; l <= n; l = r + 1) {
r = min(n / (n / l), m / (m / l));
ans += 1ll * (F[r] - F[l - 1]) * (n / l) * (m / l);
}
return ans;
}
int main() {
init();
scanf("%d", &T);
while(T--) {
scanf("%lld%lld", &n, &m);
printf("%lld\n", 1ll * n * m - calc(n, m));
}
return 0;
}