看到讨论区有人说 Min_25 筛交上去会 TLE 了,但是我在本地测所有数据梯度的极限数据都在 10s 内跑完了啊,而且交上去还开了 O3,但还是 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;
}