设 f [ i ] = ∑ j = 1 i ∑ k = 1 i [ ( i , j ) , ( i , k ) ] f[i]=\sum_{j=1}^i\sum_{k=1}^i[(i,j),(i,k)] f[i]=∑j=1i∑k=1i[(i,j),(i,k)]
不难(才怪)想到 f [ i ] f[i] f[i]是一个积性函数。
如何快速感性证明:
我们知道 g c d 、 l c m gcd、lcm gcd、lcm都是和每个质因子的指数有关,每一个质因子互不影响,对于这个题显然就是直接乘起来。
然后就是考虑 p k p^k pk怎么做,即枚举 l c m lcm lcm的大小,然后随便写写。
f ( p k ) f(p^k) f(pk)
= ( ∑ i = 0 k − 1 p i ∗ ( p k − p k − i − 1 ) 2 ∗ ( p k − p k − i ) 2 ) + p k ∗ ( 2 ∗ p k − 1 ) =(\sum_{i=0}^{k-1}p^i*(p^k-p^{k-i-1})^2*(p^k-p^{k-i})^2)+p^k*(2*p^k-1) =(∑i=0k−1pi∗(pk−pk−i−1)2∗(pk−pk−i)2)+pk∗(2∗pk−1)
= ( 2 ∗ k + 1 ) ∗ ( p 2 k − p 2 k − 1 ) + p k − 1 =(2*k+1)*(p^{2k}-p^{2k-1})+p^{k-1} =(2∗k+1)∗(p2k−p2k−1)+pk−1
有了这个套个min_25就好了。
Code:
#include
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
#define ui unsigned int
using namespace std;
const int N = 2e5 + 5;
ll n;
ll w[N]; int sqr, m, i1[N], i2[N];
int bz[N], p[N]; ui sp[3][N];
ui g[3][N];
#define num(A) ((A) <= sqr ? i1[A] : i2[n / (A)])
void sieve(int n) {
fo(i, 2, n) {
if(!bz[i]) p[++ p[0]] = i;
for(int j = 1; i * p[j] <= n; j ++) {
bz[i * p[j]] = 1;
if(i % p[j] == 0) break;
}
}
fo(i, 1, p[0]) {
ui s = 1;
fo(j, 0, 2) {
sp[j][i] = sp[j][i - 1] + s;
s *= p[i];
}
}
}
ui calc2(ll n) {
if(n & 1) return (ui)((n + 1) / 2) * n;
return (ui) (n / 2) * (n + 1);
}
ui calc3(ll n) {
ll a[3]; a[0] = n; a[1] = n + 1; a[2] = 2 * n + 1;
fo(i, 0, 2) if(a[i] % 2 == 0) { a[i] /= 2; break;}
fo(i, 0, 2) if(a[i] % 3 == 0) { a[i] /= 3; break;}
return (ui) a[0] * (ui) a[1] * (ui) a[2];
}
ui dg(ll x, int j) {
if(x <= 1 || p[j] > x) return 0;
ui s = g[2][num(x)] * 3 - g[1][num(x)] * 3 + g[0][num(x)];
s -= sp[2][j - 1] * 3 - sp[1][j - 1] * 3 + sp[0][j - 1];
for(int k = j; k <= p[0] && (ll) p[k] * p[k] <= x; k ++) {
ll p1 = p[k], p2 = p1 * p1;
ui p3 = 1, p4 = p[k], p5 = p4 * p4, sp = p5, e = 3;
for(; p2 <= x; p1 = p2, p2 *= p[k], e += 2) {
ui f = (p5 - p4) * e + p3;
ui nf = ((p5 - p4) * sp * (e + 2) + p3 * (ui) p[k]);
s += f * dg(x / p1, k + 1) + nf;
p3 = p3 * (ui) p[k];
p4 = p4 * sp;
p5 = p5 * sp;
}
}
return s;
}
int main() {
freopen("sum.in", "r", stdin);
freopen("sum.out", "w", stdout);
scanf("%lld", &n);
sqr = sqrt(n);
sieve(sqr);
for(ll i = 1, j; i <= n; i = j + 1) {
j = n / (n / i); w[++ m] = n / i;
if(w[m] <= sqr) i1[w[m]] = m; else i2[n / w[m]] = m;
g[0][m] = (ui) w[m] - 1;
g[1][m] = calc2(w[m]) - 1;
g[2][m] = calc3(w[m]) - 1;
}
for(int j = 1; j <= p[0]; j ++) {
for(int i = 1; i <= m && (ll) p[j] * p[j] <= w[i]; i ++) {
int k = num(w[i] / p[j]);
ui s = 1;
fo(t, 0, 2) {
g[t][i] -= s * (g[t][k] - sp[t][j - 1]);
s *= p[j];
}
}
}
pp("%u\n", dg(n, 1) + 1);
}