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;
}
posted @ 2017-11-23 22:34  foreignbill  阅读(324)  评论(0编辑  收藏  举报