萌新求助 TLE 的杜教筛
查看原帖
萌新求助 TLE 的杜教筛
298549
SIXIANG32楼主2023/5/25 09:51

如题,刚学杜教筛,很多细节都不知道怎么处理,希望巨佬多多指教 awa

//SIXIANG
#include <iostream>
#include <vector>
#define	MAXN 1000000
#define ll long long
using namespace std;
const int Mod = 1e6 + 3;
const int M = 1664510;

struct node {
	int id;
	ll val;
	node(int I, ll V) {
		id = I, val = V;
	}
};
vector <node> hasmu[Mod + 10], hasph[Mod + 10];
void Insertmu(int id, ll val) {hasmu[id % Mod].push_back(node(id, val));}
ll Findmu(int id) {
	for(int p = 0; p < hasmu[id % Mod].size(); p++)
		if(hasmu[id % Mod][p].id == id)
			return hasmu[id % Mod][p].val;
	return -1;
}
void Insertph(int id, ll val) {hasph[id % Mod].push_back(node(id, val));}
ll Findph(int id) {
	for(int p = 0; p < hasph[id % Mod].size(); p++)
		if(hasph[id % Mod][p].id == id)
			return hasph[id % Mod][p].val;
	return -1;
}

ll summu[M + 10], sumph[M + 10];
int pri[M + 10], ph[M + 10], mu[M + 10], tot = 0;
bool flag[M + 10];
void prepare() {
	mu[1] = ph[1] = 1;
	flag[1] = 1;
	for(int p = 2; p <= M; p++) {
		if(!flag[p]) pri[++tot] = p, mu[p] = -1, ph[p] = p - 1;
		for(int i = 1; i <= tot && pri[i] * p <= M; i++) {
			flag[pri[i] * p] = 1;
			if(p % pri[i] == 0) {
				mu[pri[i] * p] = 0;
				ph[pri[i] * p] = ph[p] * pri[i]; 
			}
			else {
				mu[pri[i] * p] = mu[pri[i]] * mu[p];
				ph[pri[i] * p] = ph[pri[i]] * ph[p];
			}
		}
	}
	for(int p = 1; p <= M; p++) {
		summu[p] = summu[p - 1] + 1ll * mu[p];
		sumph[p] = sumph[p - 1] + 1ll * ph[p];
	}
}

ll getSmu(int n) {
	if(n <= M) return summu[n];
	ll ans = 1;
	ll val = Findmu(n);
	if(val != -1) return val; 
	for(int l = 2, r; l <= n; l = r + 1) {
		r = min(n, n / (n / l));
		ans -= (r - l + 1) * getSmu(n / l);
	}
	Insertmu(n, val);
	return ans;
}
ll getSph(int n) {
	if(n <= M) return sumph[n];
	ll ans = 1ll * n * (n + 1) / 2;
	ll val = Findph(n);
	if(val != -1) return val; 
	for(int l = 2, r; l <= n; l = r + 1) {
		r = min(n, n / (n / l));
		ans -= (r - l + 1) * getSph(n / l);
	}
	Insertph(n, val);
	return ans;
}
signed main() {
	prepare();
	int T; cin >> T;
	while(T--) {
		int n; cin >> n;
		cout << getSph(n) << ' ' << getSmu(n) << endl; 
	}
}
2023/5/25 09:51
加载中...