题目大意:
设
f(n)=∑d|nμ(d)∗d
。
求
∑ni=1∑nj=1f(gcd(i,j))∗f(lcm(i,j))
1<=n<=109
题解:
把μ(d)*d看作一个整体,这是一个积性函数,卷了一个恒等函数,那么显然f是一个积性函数。
设
i=∏pq1,j=∏pq2
f(gcd(i,j))∗f(lcm(i,j))
=∏f(pmin(q1,q2))∗∏f(pmax(q1,q2))
=∏f(i)∗f(j)
于是:
Ans
=∑ni=1∑nj=1f(gcd(i,j))∗f(lcm(i,j))
=(∑ni=1f(i))2
(∑ni=1f(i)
=∑ni=1∑d|iμ(d)∗d
=∑ni=1μ(i)∗i∗⌊ni⌋
那么用杜教筛筛一下μ(i)*i这个积性函数,接着分块统计答案就好了。
设 s(n)=∑ni=1μ(i)∗i ,最后的问题是杜教筛求 s(n) 。
∑ni=1i∗∑j|iμ(j)
=1
=∑ni=1i∗∑⌊ni⌋j=1j∗μ(j)
=∑ni=1i∗s(⌊ni⌋)
s(n)
=1−∑ni=2i∗s(⌊ni⌋)
Code:
#include<cstdio>
#define ll long long
#define fo(i, x, y) for(ll i = x; i <= y; i ++)
using namespace std;
const ll mo = 1e9 + 7, M = 16491531, ni_2 = 5e8 + 4;
const ll N = 5e6;
ll n;
bool bz[N + 5]; ll p[N / 10], mu[N + 5];
ll h[M][2];
void Build() {
mu[1] = 1;
fo(i, 2, N) {
if(!bz[i]) p[++ p[0]] = i, mu[i] = -1;
fo(j, 1, p[0]) {
ll k = i * p[j];
if(k > N) break;
bz[k] = 1;
if(i % p[j] == 0) {
mu[k] = 0; break;
}
mu[k] = -mu[i];
}
}
fo(i, 1, N) mu[i] = (mu[i - 1] + mu[i] * i) % mo;
}
ll hash(ll x) {
ll y = x % M;
for(; h[y][0] != x && h[y][0] != 0; y = (y + 1) % M);
return y;
}
ll dg(ll n) {
if(n <= N) return mu[n];
ll y = hash(n);
if(h[y][0] == n) return h[y][1];
h[y][0] = n;
ll ans = 1;
fo(i, 2, n) {
ll j = n / (n / i);
ans -= (i + j) * (j - i + 1) % mo * ni_2 % mo * dg(n / i) % mo;
i = j;
}
ans = (ans % mo + mo) % mo;
h[y][1] = ans;
return ans;
}
int main() {
Build();
scanf("%lld", &n);
ll s = 0, la = 0, la2 = 0;
fo(i, 1, n) {
ll j = n / (n / i);
la2 = dg(j);
s = (s + (n / i) % mo * (la2 - la) % mo) % mo;
la = la2;
i = j;
}
printf("%lld", s * s % mo);
}