为什么第一个点就TLE了???
我处理前缀和使用的杜教筛,用第一篇题解写了一个对拍,已经拍了1W组数据了,还是没有拍出来错误数据,而且我认为我的复杂度应该是正确的吧?
求大家帮助,悬赏一个关注
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF32_MAX 2147483647
#define endl "\n"
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = x * 10 + ch - 48;
ch = getchar();
}
return x * f;
}
const int N = 1e7;
bool st[N];
int prime[N], phi[N], cnt;
unordered_map<int, int> sum_phi;
int sphi[N], MAXN;
void init()
{
phi[1] = 1;
for (int i = 2; i <= MAXN; i++)
{
if (!st[i])
{
prime[++cnt] = i;
phi[i] = i - 1;
}
for (int j = 1; prime[j] * i <= MAXN; j++)
{
st[prime[j] * i] = true;
if (i % prime[j] == 0)
{
phi[prime[j] * i] = prime[j] * phi[i];
break;
}
phi[prime[j] * i] = (prime[j] - 1) * phi[i];
}
}
for (int i = 1; i <= MAXN; i++)
sphi[i] = sphi[i - 1] + phi[i];
}
int g(int k, int x)
{
return k / (k / x);
}
int s_phi(int n)
{
if (n < MAXN)
return sphi[n];
if (sum_phi.count(n))
return sum_phi[n];
int ans = n * (n + 1) / 2;
for (int l = 2, r; l <= n; l = r + 1)
{
r = g(n, l);
ans -= (r - l + 1) * s_phi(n / l);
}
sum_phi[n] = ans;
return ans;
}
int n;
signed main()
{
// freopen("ans.in", "r", stdin);
// freopen("code.out", "w", stdout);
MAXN = pow(5e5, 2.0 / 3.0);
init();
while (cin >> n, n != 0)
{
int ans = 0;
for (int l = 1, r; l <= n; l = r + 1)
{
r = g(n, l);
ans += (s_phi(r) - s_phi(l - 1)) * (n / l) * (n / l);
}
ans -= (n * n + n) / 2;
ans /= 2;
cout << ans << endl;
}
return 0;
}