求dalao解释,为什么 O(nn) 代码能过,在本机上输入 n,m=107 最多只跑了 900ms,还是说这个复杂度跑不满吗?
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
const int N = 1e7 + 5;
const ll mod = 20101009;
int n, m;
ll prime[N], vis[N], mob[N]; int cnt;
ll sum[N], a[N];
ll calc(int n, int m) {
ll ans = 0;
for (int l = 1, r; l <= n; l = r + 1) {
r = min(n / (n / l), m / (m / l));
ans = (ans + ((sum[r] - sum[l - 1] + mod) % mod) % mod * a[n / l] % mod * a[m / l] % mod) % mod;
}
return ans;
}
int main() {
sum[1] = mob[1] = 1;
for (int i = 2; i <= 1e7; i++) {
if (!vis[i]) {
vis[i] = i;
prime[++cnt] = i;
mob[i] = -1;
}
for (int j = 1; j <= cnt && prime[j] <= 1e7 / i; j++) {
vis[prime[j] * i] = prime[j];
if (i % prime[j] == 0) {
mob[prime[j] * i] = 0;
break;
} else {
mob[prime[j] * i] = -mob[i];
}
}
sum[i] = (sum[i - 1] + mob[i] * i % mod * i % mod) % mod;
}
for (int i = 1; i <= 1e7; i++) {
a[i] = (a[i - 1] + i) % mod;
}
cin >> n >> m;
if (n > m) swap(n, m);
ll ans = 0;
for (int d = 1; d <= n; d++) {
ans = (ans + d * calc(n / d, m / d) % mod) % mod;
}
cout << ans << '\n';
return 0;
}