[BZOJ4916]神犇和蒟蒻

Portal

求:

\[\sum_{i = 1}^{n} \mu(i ^ 2) ~~~ \sum_{i = 1}^{n} \varphi(i ^ 2) \\ n \leq 1e9 \]


第一问:我有个写法可惜这里空间太小写不下:

...
    printf("1\n");
...

下面我们来考虑第二问:

对于一个素因子\(p\),我们有:

\[\varphi(p^k) = (p - 1) \times p ^{k - 1}\\ \varphi(p ^ {2k}) = (p - 1) \times p ^ {2k - 1}\\ = (p - 1) \times p ^ {k - 1} \times p^{k}\\ = \varphi(p ^ k) * p ^ k \]

所以:

\[f(n) = \varphi(n ^ 2) \\\sum_{i = 1}^{n} \varphi(i ^ 2) = \sum_{i = 1}^{n} i \times \varphi(i) \\ \]

构造$g(n) = n $, 有:

\[(f * g)(n) = \sum_{d | n} d \times \varphi(d) \times \frac{n}{d}\\ = n \sum_{d | n} \varphi(d) = n ^ 2 \]

有:$$1^2 + 2^2 + 3^2+ \dots + n^2 = \frac{n(n + 1)(2n + 1)}{6}$$

然后杜教筛搞一下就可以了。

Codes

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
int read() {
    char ch = getchar();
    int x = 0, flag = 1;
    for (;!isdigit(ch); ch = getchar()) if (ch == '-') flag *= -1;
    for (;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    return x * flag;
}
void write(int x) {
	if (x < 0) putchar('-'), x = -x;
	if (x >= 10) write(x / 10);
	putchar(x % 10 + 48);
}

const int Maxn = 3000009, Mod = (int)1e9 + 7;
__gnu_pbds :: cc_hash_table <int, LL> Sum;
LL isnprime[Maxn], prime[Maxn], tot;
LL phi[Maxn], prefix[Maxn];

void init() {
	phi[1] = 1; 
	rep (i, 2, Maxn - 1) {
		if (!isnprime[i]) {
			prime[++tot] = i;
			phi[i] = i - 1;
		}
		for (int j = 1, k; j < Maxn && (k = prime[j] * i) < Maxn; ++j) {
			isnprime[k] = 1;		
			if (i % prime[j] == 0) {
				phi[k] = prime[j] * phi[i];
				break;
			}else phi[k] = (prime[j] - 1) * phi[i];
		}
	}
	rep (i, 1, Maxn - 1) prefix[i] = (prefix[i - 1] + phi[i] * 1ll * i % Mod) % Mod;	
}

LL CalcPhiSquare(int val) {
	if (val < Maxn) return prefix[val];
	if (Sum[val]) return Sum[val];
	LL res = val * (val + 1ll) % Mod * (val * 2ll + 1) % Mod * 166666668ll % Mod;
	for (int l = 2, r; l <= val; l = r + 1) {
		r = val / (val / l);
		res -= ((r + 1ll) * r % Mod * 500000004ll % Mod - l * (l - 1ll) % Mod * 500000004ll % Mod + Mod) % Mod * CalcPhiSquare(val / l);
		(res += Mod) %= Mod;
	}
	return Sum[val] = res;
}

void solve() {
	int Index = read();
	printf("1\n%lld\n", CalcPhiSquare(Index));
}

int main() {
	freopen("BZOJ4916.in", "r", stdin);
	freopen("BZOJ4916.out", "w", stdout);

	init();
	solve();

#ifdef Qrsikno
    debug("\nRunning time: %.3lf(s)\n", clock() * 1.0 / CLOCKS_PER_SEC);
#endif
    return 0;
}
posted @ 2018-12-12 21:02  Qrsikno  阅读(149)  评论(0编辑  收藏  举报