51NOD 1237 and the greatest common divisor of V3 (Du teach sieve)

The meaning of problems

求 $\sum_{i=1}^n \sum_{j=1}^n gcd(i,j)$.

analysis

$$\begin{aligned}
\sum_{i=1}^n \sum_{j=1}^n gcd(i,j)  &= \sum_{i=1}^n \sum_{j=1}^n d[gcd(i, j)=d] \\
&= \sum_{d=1}^n d \sum_{i=1}^n \sum_{j=1}^n[gcd(i,j=d)] \\
&= \sum_{d=1}^n d \sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\mu (i) \left \lfloor \frac{n}{id} \right \rfloor\left \lfloor \frac{n}{id} \right \rfloor \\
&= \sum_{T=1}^n ({\frac{n}{T}})^2 \sum_{d|T}d\mu (\frac{T}{d}) \\
&= \sum_{T=1}^n ({\frac{n}{T}})^2 \varphi (T)
\end{aligned}$$

Use a few routines,

First $ gcd (i, j) = d $ classic summation formula;

Second emergence $ \ sum_ {d = 1} ^ nd \ sum_ {i = 1} ^ {\ left \ lfloor \ frac {n} {d} \ right \ rfloor} $, enumeration $ T = id $;

The third is to use the conclusions $ \ mu * ID = \ varphi $.

Prefix Euler function and can be used to teach Du screen.

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2000010;
typedef long long ll;
const ll mod = 1000000007;
const ll inv2 = (mod+1)>>1;
ll T, n, pri [maxn], tot, non [maxn], sum_phi [maxn];
bool vis[maxn];
unordered_map<ll, ll> mp_phi;  //可换成unordered_map
ll S_phi(ll x) {
  if (x < maxn) return sum_phi[x];
  if (mp_phi[x]) return mp_phi[x];
  ll ret = (x%mod) * ((x+1)%mod) % mod * inv2 % mod;
  for (ll i = 2, j; i <= x; i = j + 1) {
    j = x / (x / i);
    right = (Right - S_phi (x / L) * (j - i + 1 )% v + v)% v;
  }
  return mp_phi [x] = ret;
}
void initPhi()
{
  phi[1] = 1;
  for (int i = 2; i < maxn; i++) {
    if (!vis[i]) pri[++tot] = i, phi[i] = i-1;
    for (int j = 1; j <= tot && i * pri[j] < maxn; j++) {
      vis[i * pri[j]] = true;
      if (i % pri[j] == 0)
      {
          phi [i * in [i]] = phi [i] + at [a]% mod;
          break ;
      }
      else
      {
          non [i * pri [j]] = non [i] * non [pri [j]]% mod;
      }
    }
  }
  for (int i = 1; i < maxn; i++) sum_phi[i] = (sum_phi[i - 1] + phi[i]) % mod;
}

void solve()
{
    ll res = 0;
    for(ll i = 1, j;i <= n;i = j+1)
    {
        j = n / (n / i);
        ll tmp = (n/i) % mod;
        res = (res + tmp * tmp% v * (S_phi (j) -S_phi (i- 1 ) + v)% v)% v;
    }
    printf("%lld\n", res);
}

int main () {
  initPhi ();
  scanf("%lld", &n);
  solve();
  return 0;
}

 

 

Reference links:

1. http://www.ishenping.com/ArtInfo/1581096.html

2. https://oi-wiki.org/math/du/

Guess you like

Origin www.cnblogs.com/lfri/p/11701280.html