CCPC-Wannafly Winter Camp Day3 div2 F. 小清新數論* 莫比烏斯反演

小清新數論

心情:蒻蒻的第一道莫比烏斯反演!!看了好幾個小時QAQ,終於看懂些了!開心!^_^
題解(1)i=1nj=1nμ(gcd(i,j)) \sum_{i = 1}^n\sum_{j = 1}^n \mu(gcd(i,j)) \tag 1
(2)d=1ni=1nj=1nμ(d)[gcd(i,j)==d]\sum_{d = 1}^n\sum_{i = 1}^n\sum_{j = 1}^n\mu(d)[gcd(i,j) = =d]\tag 2
(3)d=1nμ(d)i=1nj=1n[gcd(i,j)==d]\sum_{d = 1}^n\mu(d)\sum_{i = 1}^n\sum_{j = 1}^n[gcd(i,j) = =d]\tag 3
g(d)=i=1nj=1n[gcd(i,j)==d]g(d) =\sum_{i = 1}^n\sum_{j = 1}^n[gcd(i,j) = =d]f(d)f(d)爲滿足dgcd(i,j)d|gcd(i,j)的對數,那麼我們就有
(4)f(d)=i=1ndg(di)f(d) = \sum_{i = 1}^{\lfloor \frac{n}{d}\rfloor}g(d\cdot i)\tag 4
如果我們要求有多少gcd(i,j)gcd(i,j)可以整除dd,那麼必定i=dx,j=dxi = d \cdot x, j = d \cdot x,因此(5)f(d)=ndndf(d) = \lfloor \frac{n}{d}\rfloor \cdot \lfloor \frac{n}{d} \rfloor\tag 5
此時我們對(4)(4)進行莫比烏斯反演
(6)g(d)=i=1ndf(di)μ(i)g(d) = \sum_{i = 1}^{\lfloor \frac{n}{d}\rfloor}f(d \cdot i)\mu(i)\tag 6
(7)g(d)=i=1ndndi2μ(i) g(d)= \sum_{i = 1}^{\lfloor \frac{n}{d}\rfloor} {\lfloor \frac{n}{d\cdot i}\rfloor }^2\mu(i)\tag 7
所以最後的(8)ans=d=1nμ(d)g(d)ans =\sum_{d = 1}^{n}\mu(d)g(d)\tag 8
最後再在求g(d)g(d)μ(d)\mu(d)的時候用除法分塊就好了,總的複雜度爲O(N)O(N)

代碼

#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
const int N = 1E7+10, mod = 998244353;
int prime[N], mu[N], cnt, n;
bool vis[N];
void get_M()
{
	mu[1] = 1;
	for(int i = 2; i < N; ++i) {
		if(vis[i] == 0) {
			prime[cnt++] = i;
			mu[i] = -1;
		}
		for(int j = 0; j < cnt && prime[j] * i < N; ++j) {
			vis[i * prime[j]] = 1;
			if(i % prime[j] == 0) break;
			mu[prime[j] * i] = -mu[i];
		}
	}
	for(int i = 1; i < N; ++i) {
		mu[i] = mu[i - 1] + mu[i];
	}
}

LL g(int d)
{
	LL ans = 0;
	for(int i = 1, last = 1; i <= n / d; i = last + 1) {
		last = n / (n / i);
		ans = (ans + (mu[last] - mu[i - 1] + mod) * (1LL * (n / d / i) * (n / d / i) % mod) ) % mod;
	}
	return ans;
}


int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.in","r",stdin);
#endif
	get_M();
	LL ans = 0;
	cin >> n;
	for(int i = 1, last = 1; i <= n; i = last + 1) {
		last = n / (n / i);
		ans = (ans + g(i) * (mu[last] - mu[i - 1] + mod)) % mod;
	}
	cout << ans << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章