HDU-5608:function

HDU-5608:function

Meaning of the questions:

Provided function \ (f (x) \) has:
\ [2-3N + 2 = N ^ \ sum_ {D | F} N (D) \]
seeking \ (\ sum_ {i = 1 } ^ Nf (i) \) .

Ideas:

Provided:
\ [F. (N-) = \ sum_ {D |} n-F (D) = n-2 ^ 2-3N + \]
Inversion obtained:
\ [F (n-) = \ sum_ {D |} n-\ MU (d) F (\ frac {
n} {d}) \] summation:
\ [\ sum_ {I}. 1 ^ = Nf of (I) = \ sum_. 1} = {I ^ N \ sum_ {D | I} \ mu (d) F (\
frac {i} {d}) \] the enumeration \ (I \) to enumerate \ (ID \) : \
[\ sum_. 1} = {D ^ N \ MU ( d) \ sum_ {i = 1
} ^ {\ frac {N} {d}} F (i) \] we can see in front of the screen may look Du teach, how the problem that the demand rear equation.
\ [\ Sum_ {i = 1
} ^ Ni ^ 2-3i + 2 \] We open a one.

First, there are square and sum formula, then there is the arithmetic series summation formula, plus a final \ (2n \) , then the problem is solved.
\ [\ Sum = \ frac { n (n + 1) (2n + 1)} {6} -3 \ frac {(n + 1) (n)} {2} + 2n \]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e6;
const int mod = 1e9+7;

bool vis[maxn+10];
int primes[maxn+10], cnt;
ll mu[maxn+10];

void init(int n)
{
    mu[1] = 1;
    for(int i = 2; i <= n; i++)
    {
        if(!vis[i])
        {
            primes[++cnt] = i;
            mu[i] = -1;
        }
        for(int j = 1; primes[j] <= n/i; j++)
        {
            vis[primes[j]*i] = 1;
            if(i % primes[j] == 0) break;
            else mu[i*primes[j]] = -mu[i];
        }
    }
    for(int i = 1; i <= n; i++)
        mu[i] += mu[i-1], mu[i] %= mod;
}

unordered_map<ll, ll> Smu;
inline ll getSmu(ll n)
{
    if(n <= maxn) return mu[n];
    if(Smu[n]) return Smu[n];
    ll res = 1;
    for(ll l = 2, r; l <= n; l = r+1)
    {
        r = n/(n/l);
        res -= (r-l+1)%mod*getSmu(n/l)%mod;
        res = (res+mod)%mod;
    } return Smu[n] = res;
}

const ll inv6 = 166666668;
const ll inv2 = 500000004;
ll S(ll x)
{
    ll res = 0;
    res += x*(x+1)%mod*(2*x+1)%mod*inv6%mod; res %= mod;
    res -= 3*(x+1)%mod*(x)%mod*inv2%mod;  res %= mod;
    res += 2*x%mod; res %= mod;
    return res;
}

ll n;
void solve()
{
    scanf("%lld", &n);
    ll ans = 0;
    for(ll l = 1, r; l <= n; l = r+1)
    {
        r = n/(n/l);
        ans += ((getSmu(r)-getSmu(l-1))%mod+mod)%mod*S(n/l)%mod;
        ans %= mod;
    }
    printf("%lld\n", ans);
}

int main()
{
    init(maxn);
    int T; scanf("%d", &T);
    while(T--) solve();
    return 0;
}

Guess you like

Origin www.cnblogs.com/zxytxdy/p/12425864.html