求问复杂度
查看原帖
求问复杂度
999274
CNS_5t0_0r2楼主2024/9/3 20:21

这是我的代码(按照官方题解数论分块套杜教筛的思路写的):

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int SqrtN = 15e5 + 9,MOD = 998244353;
int n,v;
bool is_not_prime[SqrtN] = {1,1};
int prime[SqrtN],top;
int mu[SqrtN],sum_mu[SqrtN]; 
int ans;
void sieve(){
	v = 15e5;
	mu[1] = 1;
	for(int i = 2;i <= v;i++){
		if(!is_not_prime[i]){
			prime[++top] = i;
			mu[i] = -1;
		}
		for(int j = 1;j <= top && i * prime[j] <= v;j++){
			is_not_prime[i * prime[j]] = 1;
			if(i % prime[j] == 0)
				break;
			mu[i * prime[j]] = -mu[i];
		}
	}
	for(int i = 1;i <= v;i++)
		sum_mu[i] = sum_mu[i - 1] + mu[i];
}
unordered_map<int,int> s_mu;
int SumMu(int n){
	if(n <= v)
		return sum_mu[n];
	if(s_mu[n])
		return s_mu[n];
	int ret = 1;
	for(int l = 2,r;l <= n;l = r + 1){
		r = n / (n / l);
		ret -= (r - l + 1) * SumMu(n / l);
	}
	return s_mu[n] = ret;
}
int qpow(int x,int y,int MOD){
	int ret = 1;
	while(y){
		if(y & 1)
			ret = ret * x % MOD;
		x = x * x % MOD;
		y >>= 1;
	}
	return ret;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> n;
	sieve();
	for(int l = 1,r;l <= n;l = r + 1){
		r = n / (n / l);
		ans = (ans + (SumMu(r) - SumMu(l - 1) + MOD) % MOD * qpow(n / l,3,MOD)) % MOD;
	}
	cout << ans;
	return 0;
}

我不知道为什么复杂度为 O(n23)O(n ^ \frac{2}{3})(别告诉我复杂度是直接数论分块复杂度乘杜教筛的复杂度),但实测告诉我很有可能根记忆化有关,求大佬解答。

2024/9/3 20:21
加载中...