萌新求助 Min_25 筛
查看原帖
萌新求助 Min_25 筛
137603
zhiyangfanshotacon楼主2022/1/14 10:59

看到讨论区有人说 Min_25 筛交上去会 TLE\tt TLE 了,但是我在本地测所有数据梯度的极限数据都在 10s\tt 10s 内跑完了啊,而且交上去还开了 O3\tt O3,但还是 TLE\tt TLE 飞了,求为啥。

#include <cmath>
#include <cstdio>
const int N = 2e6 + 10; typedef long long ll; typedef unsigned long long ull;
ll n, w[N]; ull g[N]; int p[N], vis[N], ind1[N], ind2[N], tp, tot, sqrn;
inline void getP()
{
	vis[1] = 1;
	for (int i = 2; i < N; ++i)
	{
		if (!vis[i]) p[++tp] = i;
		for (int j = 1; j <= tp && (ll)p[j] * i < N; ++j)
		{
			vis[i * p[j]] = 1;
			if (i % p[j] == 0) break;
		}
	}
}
ull S(ll x, int y)
{
	if (p[y] >= x) return 0;
	int k = x <= sqrn ? ind1[x] : ind2[n / x];
	ull ans = g[k] - y * 3;
	for (int i = y + 1; i <= tp && (ll)p[i] * p[i] <= x; ++i)
	{
		ll pe = p[i];
		for (int e = 1; pe <= x; ++e, pe *= p[i])
			ans += (2 * e + 1) * (S(x / pe, i) + (e != 1));
	}
	return ans;
}
int main()
{
	int T; scanf("%d", &T); getP();
	while (T--)
	{
		scanf("%lld", &n); sqrn = sqrt(n); tot = 0; 
		for (ll l = 1, r; l <= n; l = r + 1)
		{
			r = (n / (n / l)); w[++tot] = n / l; g[tot] = w[tot] - 1;
			if (w[tot] <= sqrn) ind1[w[tot]] = tot;
			else ind2[n / w[tot]] = tot;
		}
		for (int i = 1; i <= tp; ++i)
		{
			ll p2 = (ll)p[i] * p[i];
			for (int j = 1; j <= tot && p2 <= w[j]; ++j)
			{
				int k = w[j] / p[i] <= sqrn ? ind1[w[j] / p[i]] : ind2[n / (w[j] / p[i])];
				g[j] -= (g[k] - (i - 1));
			}
		}
		for (int i = 1; i <= tot; ++i) g[i] *= 3; printf("%llu\n", S(n, 0) + 1);
	}
	return 0;
}
2022/1/14 10:59
加载中...