HDU 5942
$f(k)$表示k的因子数,$g(k)=2^{f(k)}$,那么$g(k)$表示的就是$k$的非平方以上因子的个数。
那么$g(k)=\sum_{d|k} \mu^2(k)$。
那么就是求$\sum_{i=1}^{n} \sum_{d|i} \mu^2(d)$。
$\sum_{d|i} \mu^2(k)=\sum_{d|i} \sum_{k^2|d} \mu(k)$,
交换sigma顺序。
$\sum_{k=1}^{\sqrt(n)} \mu(k) \sum_{d=1}^{\left \lfloor \frac{n}{k^2} \right \rfloor} \left \lfloor \frac{n}{k^2d} \right \rfloor$。
前面$O(\sqrt(n))$复杂度求,后面大数据分块求,小数据分块加记忆化。复杂度不会计算。。。
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
ll n;
const int N = 1e6;
bool p[N + 5];
int prime[N + 5], top;
int mu[N + 5];
ll res;
ll f[N + 5];
void init() {
memset(p, 0, sizeof p);
mu[1] = 1;
top = 0;
for (int i = 2; i <= N; ++i) {
if (!p[i]) {
prime[++top] = i;
mu[i] = -1;
}
for (int j = 1; j <= top; ++j) {
if (i * prime[j] > N) break;
p[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
mu[i * prime[j]] = -mu[i];
}
}
}
ll calc(ll n) {
if (n <= N && f[n]) return f[n];
ll ret = 0;
for (ll i = 1, lst; i <= n; i = lst + 1) {
lst = n / (n / i);
ret += (n / i) * (lst - i + 1);
ret %= mod;
}
if (n <= N) f[n] = ret;
return ret;
}
int main() {
//freopen("in.txt","r",stdin);
init();
int T, cas = 1;
memset(f, 0, sizeof f);
for (cin >> T; T--;) {
cin >> n;
res = 0;
for (ll i = 1; i * i <= n; i++) {
if (mu[i]) {
(res += mu[i] * calc(n / i / i) % mod) %= mod;
}
}
res = (res % mod + mod) % mod;
cout << "Case #" << cas++ << ": " << res << endl;
}
return 0;
}