LOJ 6053 時間複雜度 min25篩

ffnn 項的和對 2019060120190601 取模的值。

1n10111\le n\le 10^{11}

考慮 min_25 篩中的 g0(n,j)g_0(n,j)00 次方,即滿足條件的數的個數)和 g0(n,j1)g_0(n,j-1)

g0(n,j)=i=1n[iprime  minp(i)>pj]g_0(n,j)=\sum\limits^n_{i=1}[i\in prime\ ||\ minp(i)>p_j]

g0(n,j1)=i=1n[iprime  minp(i)pj]g_0(n,j-1)=\sum\limits^n_{i=1}[i\in prime\ ||\ minp(i)\ge p_j]

特別地,有 g0(n,0)=n1g_0(n,0)=n-1

所以 g0(n,j1)g0(n,j)=i=1n[iprime && minp(i)=pj]g_0(n,j-1)-g_0(n,j)=\sum\limits^n_{i=1}[i\notin prime\ \&\&\ minp(i)=p_j]

也就是最小質因子爲 pjp_j 的數的個數。(不包括 pjp_j

那麼答案爲 j=1Ppj(g0(n,j1)g0(n,j)+1)(n1)g0(n,P)\sum\limits^{|P|}_{j=1}p_j(g_0(n,j-1)-g_0(n,j)+1)-(n-1)-g_0(n,|P|)

……嗎?

由於 min_25 篩只能處理到 n\le \sqrt{n} 的質數,所以 >n>\sqrt{n} 的質數不會被統計到。

所以分質數和合數兩類討論。合數部分上面討論完了。質數部分是模板。

答案爲 j=1Ppj(g0(n,j1)g0(n,j))+g1(n,P)(n1)g0(n,P)\sum\limits^{|P|}_{j=1}p_j(g_0(n,j-1)-g_0(n,j))+g_1(n,|P|)-(n-1)-g_0(n,|P|)

時間複雜度 O(n3/4logn)O(\dfrac{n^{3/4}}{\log n})

以上題解轉自https://www.cnblogs.com/1000Suns/p/10888832.html

以下是本人代碼:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1000005;
const int mod = 20190601, inv2 = 10095301;
LL n, a[MAXN];
int m, sqr, s[2][MAXN];
inline int cal(LL N) { N%=mod; return 1ll*N*(N+1)%mod*inv2%mod; }
inline int ID(LL x) { return x <= sqr ? x : m-n/x+1; }
int main () {
	cin>>n; sqr = sqrt(n);
	for(LL i = 1; i <= n; ++i)
		a[++m] = i = n/(n/i),
		s[0][m] = i%mod-1,
		s[1][m] = cal(i)-1;
	int ans = 0;
	for(int i = 2; i <= sqr; ++i) if(s[0][i]^s[0][i-1]) {
		ans = (ans + 1ll*(s[0][ID(n/i)]-s[0][i-1])*i) % mod;
		for(int j = m; a[j] >= 1ll*i*i; --j) {
			s[0][j] = (s[0][j] - 1ll*(s[0][ID(a[j]/i)]-s[0][i-1])) % mod;
			s[1][j] = (s[1][j] - 1ll*i*(s[1][ID(a[j]/i)]-s[1][i-1])) % mod;
		}
	}
	ans = (ans + s[1][m]) % mod;
	ans = (ans - n%mod + 1) % mod;
	ans = (ans - s[0][m]) % mod;
	printf("%d\n", (ans + mod) % mod);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章