【51nod 1238】最小公倍数之和

题意:求 i = 1 n j = 1 n l c m ( i , j ) \sum_{i=1}^n\sum_{j=1}^nlcm(i, j)

题解:

原式可化为:
i = 1 n j = 1 n i j g c d ( i , j ) \sum_{i=1}^n\sum_{j=1}^n\frac{ij}{gcd(i, j)}
i = 1 n j = 1 n d = 1 n i j d [ d = g c d ( i , j ) ] \sum_{i=1}^n\sum_{j=1}^n\sum_{d=1}^n\frac{ij}{d}[d=gcd(i, j)]
将i, 改为 i d id ,j改为 j d jd
d = 1 n d i = 1 n d i j = 1 n d j [ g c d ( i , j ) = 1 ] \sum_{d=1}^nd\sum_{i=1}^{\lfloor{\frac{n}{d}}\rfloor}i\sum_{j=1}^{\lfloor{\frac{n}{d}}\rfloor}j[gcd(i, j)=1]
引理1: i = 1 n i [ g c d ( n , i ) = 1 ] = n ϕ ( n ) + [ n = 1 ] 2 \sum_{i=1}^{n}i[gcd(n, i)=1]=\frac{n\phi{(n)}+[n=1]}{2}
理由如下:
由于对任意 g c d ( n , i ) = 1 gcd(n,i)=1 ,由辗转相除得: g c d ( n , n i ) = 1 gcd(n, n-i)=1
i = 1 n i [ g c d ( n , i ) = 1 ] = n ϕ ( n ) + [ n = 1 ] 2 \sum_{i=1}^{n}i[gcd(n, i)=1]=\frac{n\phi{(n)}+[n=1]}{2}
继续化简:
i = j = 1 i=j=1 ,则会被多算一次,故减1
i = j n i=j\neq{n} ,则 g c d ( i , j ) 1 gcd(i,j)\neq{1} ,故不会被重复 计算

d = 1 n d ( 2 i = 1 n d i j = 1 i j [ g c d ( i , j ) = 1 ] 1 ) \sum_{d=1}^nd(2\sum_{i=1}^{\lfloor{\frac{n}{d}}\rfloor}i\sum_{j=1}^{i}j[gcd(i, j)=1]-1)
由引理1:
d = 1 n d ( 2 i = 1 n d i i ϕ ( i ) + [ i = 1 ] 2 1 ) \sum_{d=1}^nd(2\sum_{i=1}^{\lfloor{\frac{n}{d}}\rfloor}i\frac{i\phi{(i)+[i=1]}}{2}-1)
i = 1 i=1 时, i ϕ ( i ) + [ i = 1 ] 2 = 1 \frac{i\phi{(i)+[i=1]}}{2}=1

d = 1 n d i = 1 n d i 2 ϕ ( i ) \sum_{d=1}^nd\sum_{i=1}^{\lfloor{\frac{n}{d}}\rfloor}i^2\phi{(i)}
用杜教筛求 i = 1 n d i 2 ϕ ( i ) \sum_{i=1}^{\lfloor{\frac{n}{d}}\rfloor}i^2\phi{(i)}

g ( x ) = i = 1 n i 2 d = 1 i [ d i ] ϕ ( d ) g(x)=\sum_{i=1}^ni^2\sum_{d=1}^i[d|i]\phi{(d)}
s ( x ) = i = 1 n i 2 ϕ ( i ) s(x)=\sum_{i=1}^ni^2\phi{(i)}
由于 d = 1 i [ d i ] ϕ ( d ) = i \sum_{d=1}^i[d|i]\phi{(d)}=i
g ( x ) = i = 1 n i 3 = n 2 ( n + 1 ) 2 4 g(x)=\sum_{i=1}^ni^3=\frac{n^2(n+1)^2}{4}
s ( x ) = g ( x ) i = 2 x i 2 d = 1 i 1 [ d i ] ϕ ( d ) s(x)=g(x)-\sum_{i=2}^{x}i^2\sum_{d=1}^{i-1}[d|i] \phi{(d)}
s ( x ) = g ( x ) i = 2 x i 2 d = 1 x i d ϕ ( d ) s(x)=g(x)-\sum_{i=2}^{x}i^2\sum_{d=1}^{\lfloor{\frac{x}{i}}\rfloor} d\phi{(d)}
s ( x ) = g ( x ) i = 2 x i 2 s ( x i ) s(x)=g(x)-\sum_{i=2}^{x}i^2s(\lfloor{\frac{x}{i}}\rfloor)

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define ll long long
using namespace std;
const int mn = 5000005, mod = 1000000007, inv4 = 250000002, inv2 = 500000004, inv6 = 166666668;
map<ll, ll> s;
ll phi[mn], pri[mn];
int cnt;
bool vis[mn];
inline void init(int n)
{
    phi[1] = 1;
    for(int i = 2; i <= n; i++)
    {
        if(!vis[i])
            phi[i] = i - 1, pri[++cnt] = i;
        for(int j = 1; j <= cnt && pri[j] * i <= n; j++)
        {
            vis[pri[j] * i] = 1;
            if(i % pri[j] == 0)
            {
                phi[pri[j] * i] = pri[j] * phi[i] % mod;
                break;
            }
            phi[pri[j] * i] = (pri[j] - 1) * phi[i] % mod;
        }
    }
    for(int i = 1; i <= n; i++)
        phi[i] = phi[i] * i % mod * i % mod;
    for(int i = 1; i <= n; i++)
        phi[i] += phi[i - 1], phi[i] %= mod;
}
ll h(ll x)
{
    x %= mod;
    return x * (x + 1) % mod * (2ll * x % mod + 1) % mod * inv6 % mod;
}
ll S(ll n)
{
    if(n <= mn - 5)
        return phi[n];
    if(s.find(n) != s.end())
        return s[n];
    ll ret = n % mod * (n % mod) % mod * ((n % mod + 1) % mod) % mod * ((n % mod + 1) % mod) % mod * inv4 % mod;
    for(ll i = 2, las; i <= n; i = las + 1)
        las = n / (n / i), ret -= (h(las) - h(i - 1)) % mod * S(n / i) % mod, ret = (ret % mod + mod) % mod;
    return s[n] = ret;
}
int main()
{
    ll n;
    scanf("%lld", &n);
    init(min(n, (ll)(mn - 5)));
    ll ans = 0;
    for(ll i = 1, las; i <= n; i = las + 1)
        las = n / (n / i), ans += (i % mod + las % mod) % mod * (las - i + 1) % mod * inv2 % mod * S(n / i) % mod, ans %= mod;
    printf("%lld\n", ans);
}

猜你喜欢

转载自blog.csdn.net/C20181503csy/article/details/84948029
今日推荐