2019ICPC南京网络赛 E.K Sum 反演+杜教筛

E.K Sum

Problem

Def. f n ( k ) = ∑ l 1 = 1 n ∑ l 2 = 1 n . . . ∑ l k = 1 n ( g c d ( l 1 , l 2 , . . . , l k ) ) 2 f_n(k) = \sum_{l_1=1}^n \sum_{l_2 = 1}^n ...\sum_{l_k=1}^n (gcd(l_1, l_2, ...,l_k))^2 fn(k)=l1=1nl2=1n...lk=1n(gcd(l1,l2,...,lk))2
Give n, Calculate ∑ i = 2 k f n ( i ) ( m o d 1 e 9 + 7 ) \sum_{i=2}^k f_n(i) \pmod{1e9 + 7} i=2kfn(i)(mod1e9+7)

1 ≤ n ≤ 1 0 9 1 \leq n \leq 10^9 1n109
2 ≤ k ≤ 1 0 1 0 5 2 \leq k \leq 10^{10^5} 2k10105

Solution

f n ( k ) = ∑ i = 1 n ∑ l 1 = 1 n ∑ l 2 = 1 n . . . ∑ l k = 1 n i 2 ⋅ [ ( l 1 , l 2 , . . . , l k ) = i ] = ∑ i = 1 n ∑ l 1 = 1 ⌊ n i ⌋ ∑ l 2 = 1 ⌊ n i ⌋ . . . ∑ l k = 1 ⌊ n i ⌋ i 2 ⋅ [ ( l 1 , l 2 , . . . , l k ) = 1 ] \begin{aligned} f_n(k)&=\sum_{i=1}^n \sum_{l_1=1}^n \sum_{l_2=1}^n ... \sum_{l_k=1}^n i^2 \cdot [(l_1,l_2,...,l_k)=i] \\ &=\sum_{i=1}^n \sum_{l_1=1}^{\lfloor \frac{n}{i} \rfloor} \sum_{l_2=1}^{\lfloor \frac{n}{i} \rfloor} ... \sum_{l_k=1}^{\lfloor \frac{n}{i} \rfloor} i^2 \cdot [(l_1, l_2,...,l_k) = 1] \end{aligned} fn(k)=i=1nl1=1nl2=1n...lk=1ni2[(l1,l2,...,lk)=i]=i=1nl1=1inl2=1in...lk=1ini2[(l1,l2,...,lk)=1]
反演可得
f n ( k ) = ∑ i = 1 n ∑ l 1 = 1 ⌊ n i ⌋ ∑ l 2 = 1 ⌊ n i ⌋ . . . ∑ l k = 1 ⌊ n i ⌋ i 2 ∑ d ∣ ( l 1 , l 2 , . . . , l k ) μ ( d ) = ∑ i = 1 n i 2 ∑ d = 1 ⌊ n i ⌋ μ ( d ) ⋅ ∑ l 1 = 1 ⌊ n i ⋅ d ⌋ ∑ l 2 = 1 ⌊ n i ⋅ d ⌋ . . . ∑ l k = 1 ⌊ n i ⋅ d ⌋ 1 = ∑ i = 1 n i 2 ∑ d = 1 ⌊ n i ⌋ μ ( d ) ⋅ ⌊ n i ⋅ d ⌋ k = ∑ l = 1 n ⌊ n l ⌋ k ∑ d ∣ l μ ( d ) ⋅ ( l d ) 2 \begin{aligned} f_n(k)&=\sum_{i=1}^n \sum_{l_1=1}^{\lfloor \frac{n}{i} \rfloor} \sum_{l_2=1}^{\lfloor \frac{n}{i} \rfloor} ... \sum_{l_k=1}^{\lfloor \frac{n}{i} \rfloor} i^2 \sum_{d | (l_1, l_2, ...,l_k)} \mu(d) \\ &=\sum_{i=1}^n i^2 \sum_{d = 1}^{\lfloor \frac{n}{i} \rfloor} \mu(d) \cdot \sum_{l_1=1}^{\lfloor \frac{n}{i \cdot d} \rfloor}\sum_{l_2=1}^{\lfloor \frac{n}{i \cdot d} \rfloor}...\sum_{l_k=1}^{\lfloor \frac{n}{i \cdot d} \rfloor} 1\\ &=\sum_{i=1}^n i^2 \sum_{d = 1}^{\lfloor \frac{n}{i} \rfloor} \mu(d) \cdot \lfloor \frac{n}{i \cdot d} \rfloor^k\\ &=\sum_{l=1}^n \lfloor \frac{n}{l} \rfloor ^k \sum_{d|l}\mu(d) \cdot (\frac{l}{d})^2 \end{aligned} fn(k)=i=1nl1=1inl2=1in...lk=1ini2d(l1,l2,...,lk)μ(d)=i=1ni2d=1inμ(d)l1=1idnl2=1idn...lk=1idn1=i=1ni2d=1inμ(d)idnk=l=1nlnkdlμ(d)(dl)2
f n ( i ) f_n(i) fn(i)求前缀和得
∑ i = 2 k f n ( i ) = ∑ i = 2 k ∑ l = 1 n ⌊ n l ⌋ i ∑ d ∣ l μ ( d ) ⋅ ( l d ) 2 = ∑ l = 1 n ( ∑ i = 2 k ⌊ n l ⌋ i ) ( ∑ d ∣ l μ ( d ) ⋅ ( l d ) 2 ) = ∑ l = 1 n T 1 ⋅ T 2 \begin{aligned} \sum_{i=2}^k f_n(i)&=\sum_{i=2}^k \sum_{l=1} ^n \lfloor \frac{n}{l} \rfloor ^i \sum_{d|l}\mu(d) \cdot (\frac{l}{d})^2\\ &=\sum_{l=1}^n (\sum_{i=2}^k \lfloor \frac{n}{l} \rfloor ^i)(\sum_{d|l} \mu(d) \cdot (\frac{l}{d})^2)\\ &=\sum_{l=1}^n T_1 \cdot T_2 \end{aligned} i=2kfn(i)=i=2kl=1nlnidlμ(d)(dl)2=l=1n(i=2klni)(dlμ(d)(dl)2)=l=1nT1T2
对于 T 1 T_1 T1,先用欧拉定理对k降幂后,可以使用等比数列求和公式直接求得,并特殊处理公比为1得情况。
对于 T 2 T_2 T2,用杜教筛。令 g ( n ) = ∑ d ∣ n μ ( d ) ⋅ ( n d ) 2 g(n) = \sum_{d | n} \mu(d) \cdot (\frac{n}{d}) ^ 2 g(n)=dnμ(d)(dn)2
由于 μ , i d \mu,id μ,id都是积性函数,所以它们的狄利克雷卷积 g ( n ) g(n) g(n)为积性函数。
因此
g ( 1 ) = 1 g ( p ) = p 2 − 1 g ( p k + 1 ) = p 2 k + 2 − p 2 k = g ( p ) ⋅ p 2 k \begin{aligned} g(1) &= 1 \\ g(p) &= p^2 - 1\\ g(p^{k+1}) &= p^{2k+2} - p^{2k} = g(p) \cdot p^{2k} \end{aligned} g(1)g(p)g(pk+1)=1=p21=p2k+2p2k=g(p)p2k
则以上部分可用欧拉筛求得5e6内的值。
由于 g × I = μ × i d 2 × I = μ × I × i d 2 = i d 2 g \times I = \mu \times id^2 \times I=\mu \times I \times id^2 = id^2 g×I=μ×id2×I=μ×I×id2=id2
则对其求前缀和有
n ( n + 1 ) ( 2 n + 1 ) 6 = ∑ i = 1 n i 2 = ∑ i = 1 n ∑ d ∣ i μ ( d ) ⋅ ( i d ) 2 = ∑ i d = 1 n ∑ d = 1 ⌊ n i d ⌋ μ ( d ) ⋅ ( i d ) 2 = ∑ i = 1 n G ( ⌊ n i ⌋ ) \frac{n(n+1)(2n+1)}{6} = \sum_{i=1}^n i^2 = \sum_{i=1}^n \sum_{d|i} \mu(d) \cdot (\frac{i}{d})^2=\sum_{\frac{i}{d}=1}^n \sum_{d=1}^{\lfloor \frac{n}{\frac{i}{d}} \rfloor} \mu(d) \cdot (\frac{i}{d})^2 =\sum_{i=1}^n G(\lfloor \frac{n}{i} \rfloor) 6n(n+1)(2n+1)=i=1ni2=i=1ndiμ(d)(di)2=di=1nd=1dinμ(d)(di)2=i=1nG(in)
G ( n ) = n ( n + 1 ) ( 2 n + 1 ) 6 − ∑ i = 2 n G ( ⌊ n i ⌋ ) G(n) = \frac{n(n+1)(2n+1)}{6} - \sum_{i=2}^{n}G(\lfloor \frac{n}{i} \rfloor) G(n)=6n(n+1)(2n+1)i=2nG(in)
总体复杂度 O ( n 2 3 + n ⋅ l o g 1 0 9 ) O(n^{\frac{2}{3}} + \sqrt n \cdot log 10^9) O(n32+n log109)

// Cease to struggle and you cease to live
// E.cpp
// Created by Nickwzk on 2019_09_22 13:20
#include 
using namespace std;

typedef long long LL;
const int MAXN = 5e6 + 5, mod = 1e9 + 7;
int prime[MAXN], cnt;
LL g[MAXN], G[MAXN];
int fac[MAXN];
LL fac_pow[MAXN];
bool isp[MAXN];
unordered_map<LL, int> mp;
void Euler(int n) {
	fac_pow[1] = g[1] = fac[1] = 1;
	for(int i = 2; i <= n; i++) {
		if(!isp[i]) {
			prime[++cnt] = i;
			fac_pow[i] = fac[i] = i;
			g[i] = ((LL)i * i - 1) % mod;
		}
		for(int j = 1; j <= cnt && i * prime[j] <= n; j++) {
			isp[i * prime[j]] = 1;
			if(i % prime[j] == 0) {
				fac[i * prime[j]] = fac[i];
				fac_pow[i * prime[j]] = fac_pow[i] * prime[j];
				g[i * prime[j]] = g[fac[i]] * g[i / fac_pow[i]] % mod * fac_pow[i] % mod * fac_pow[i] % mod;
				break;
			}
			fac_pow[i * prime[j]] = fac[i * prime[j]] = prime[j];
			g[i * prime[j]] = g[i] * g[prime[j]] % mod;
		}
	}
	for(int i = 1; i <= n; i++) {
		G[i] = (G[i - 1] + g[i]) % mod;
	}
}
LL qpow(LL x, LL y) {
	LL res = 1;
	while(y) {
		if(y & 1) res = res * x % mod;
		x = x * x % mod;
		y >>= 1;
	}
	return res;
}
LL inv(LL x) {
	x = (x + mod) % mod;
	return qpow(x, mod - 2);
}
LL cal(LL n) {
	if(n < MAXN) return G[n];
	if(mp.count(n)) return mp[n];
	LL res = 0;
	for(LL i = 2, last; i <= n; i = last + 1) {
		last = n / (n / i);
		res += (last - i + 1) % mod * cal(n / i) % mod;
		res %= mod;
	}
	return mp[n] = ((__int128)n * (n + 1) * (2 * n + 1) / 6 % mod + mod - res) % mod;
}
inline LL get(LL n, LL x, LL y) {
	if(n == 1) return y;
	return n * n % mod * (mod + 1 - qpow(n, x)) % mod * inv(1 - n) % mod;
}
int main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.precision(6); cout << fixed;
	Euler(MAXN - 1);
	int T; cin >> T;
	LL n; string k;
	LL x, y;
	while(T--) {
		cin >> n >> k;
		x = y = 0;
		for(auto c : k) {
			x = x * 10 + c - '0';
			y = y * 10 + c - '0';
			x %= mod - 1;
			y %= mod;
		}
		x = (x - 1 + mod - 1) % (mod - 1);
		y = (y - 1 + mod) % mod;
		LL ans = 0;
		for(LL i = 1, last; i <= n; i = last + 1) {
			last = n / (n / i);
			ans += get(n / i % mod, x, y) * (cal(last) - cal(i - 1) + mod) % mod;
			ans %= mod;
		}
		cout << ans << endl;
	}
	return 0;
}

你可能感兴趣的:(数论)