Luo Gu P3768 simple math problems Du teach Mobius inversion screen +

Luo Gu P3768 simple math problems

label

  • Mobius inversion
  • Dirichlet convolution
  • Du teach sieve

Foreword

  • Very simple good push ~

Concise meaning of the questions

  • Seeking
    \ [\ sum_ {i = 1 } \ sum_ ^ ( mod p lower sense) nijgcd (i, j) ^ n {j = 1} \]

Thinking

  • Very simple duck. Push down again on the out ~
    \ [\ sum_. 1} ^ {n-I = \ sum_ {J} = ^ nijgcd. 1 (I, J) \]
  • To enumerate GCD:
    \ [\ sum_ = {X ^}. 1 NX \ sum_. 1} ^ {n-I = \ sum_. 1} = {J ^ NIJ [GCD (I, J) == X] \]

    They are routine ah! Doubly appearing in formulas \ (gcd (i, J) \) , then changed to enumerate

  • See the \ ([gcd (i, j ) == x] \) too familiar, but I say step by step. First replace enumeration limit:
    \ [\ sum_. 1} = X ^ {^. 3 NX \ sum_. 1 = {I} ^ {[\ NX FRAC]} \ sum_. 1} = {J ^ {[\ NX FRAC]} ij of [gcd (i, j) == 1] \]

    Here briefly about why \ (the X-^ 3 \) . After replacing the cap because enumeration, enumeration that is the original \ (\ FRAC 1x \) , so ij have become old \ (\ FRAC 1x \) , so it should be multiplied by \ (the X-^ 2 \) , and then moved to the front is \ (x ^ 3 \) a

  • Then inversion duck, with \ (\ sum_ {d | n } \ mu (d) \) Alternatively \ ([GCD (I, J) ==. 1] \) , and the \ (d | gcd (i, j ) \) to \ (d | i and d | j \) to give:
    \ [\ sum_. 1} = X ^ {^. 3 NX \ sum_. 1 = {I} ^ {[\ NX FRAC]} \ sum_ {J = 1} ^ {[\ frac nx]} ij \ sum_ {d | i and d | j} \ mu (d ) \]

    I remember the nature of the gcd: \ (d | gcd (i, J) \ IFF d | i and d | j \)

  • Then the routine again, after the replacement to enumerate d, is then:
    \ [\ sum_. 1} = X ^ {^. 3 NX \ sum_. 1 = {D} ^ {[\ NX FRAC]} \ MU ( d) \ sum_ {i = 1 } ^ {[\ frac nx]} \ sum_ {j = 1} ^ {[\ frac nx]} ij [d | i and d | j] \]
  • Then see \ ([d | i and d | j] \) we could not help but change with the upper limit of the enumeration, remember to change the upper limit, the number of enumeration became the original \ (\ frac 1d \) , it should take back:
    \ [\ sum_ {X =. 1} ^ NX ^. 3 \ sum_ {D =. 1} ^ {[\ FRAC NX]} \ MU (D) \ sum_ {I =. 1} ^ {[\ frac n {dx}]} \ sum_ {j = 1} ^ {[\ frac n {dx}]} ijd ^ 2 \]
  • Primary oersted tells us \ (G (X) = \ SUM \ limits_ {I =. 1} ^ X \ SUM \ limits_ {J =. 1} ^ xij = X ^ 2 * (X +. 1) ^ 2 /. 4 \) , so the original formula is actually seeking:
    \ [\ sum_ {X =. 1} ^ n-\ sum_ {D =. 1} ^ {[\ FRAC NX]} \ MU (D) G ([\ FRAC n-{DX}]) D ^ 2x ^ 3 \]

    The above equation is the primary Mathematical Olympiad joke. It is actually derived: \ (G (X) = \ SUM \ limits_. 1} ^ {X = I \ SUM \ limits_ J = {xij. 1} ^ = \ SUM \ limits_. 1} = {I ^ XI \ SUM \ limits_ {i = 1} ^ xi = (n * (n + 1) / 2) ^ 2 \)

  • A look at this time, the upper limit of the relationship between x and d, found enumeration can be replaced, instead we enumerate \ (DX = K \) , then the original formula is:
    \ [\ sum_. 1} ^ {K = NK ^ 2g ([\ frac nk] ) \ sum_ {d | k} \ mu (\ frac kd) d \]

    This step was changed to enumerate how \ (K = dx \) and do not know the students look at my blog "number theory formula summary" poke here

  • Obviously \ (\ sum \ limits_ {d | k} \ mu (\ frac kd) d \) is \ (\ mu and id \) of the Dirichlet convolution duck! Well known \ (\ MU ID = * \ Phi \) , we find the actual:
    \ [\ sum_ K = {}. 1 NK ^ ^ 2 \ Phi (K) G ([\ FRAC NK]) \]
  • Here's a look inside the g \ (\ FRAC NK \) , you know you want to block the oh ~ so we need to find \ (k ^ 2 \ mu ( k) \) prefix and violence is clearly not enough, so we teach Du sieve chant, so the question now is how to teach Du screen

  • Is now required \ (x ^ 2 \ phi ( x) \) prefix and, we set \ (F (X) = X ^ 2 \ Phi (X) \) , find a function \ (g (x) \) , then Du teach sift:
    \ [S (n-) G (. 1) = \ sum_ {I}. 1 ^ = NF * G- \ sum_ {2} = I ^ ng (I) S ([\ Ni FRAC ]) \]
  • In fact, when Du teach sieve find \ (g (x) \) , they often pay more attention \ (f * g \) prefix and good demand of Dirichlet convolution, usually both convolution is \ (\ Epsilon \) or \ (ID \) or \ (\ Phi (n-) \) . So now a need to find \ (G (X) \) , such that \ (f * g \) is \ (\ Epsilon \) or \ (ID \) . We write the convolution of both:
    \ [(F * G) (n-) = \ sum_ {D |} n-F (D) G ([\ FRAC Nd]) \]
  • We \ (f (x) = x ^ 2 \ phi (x) \) with in, derived \ (F \) and \ (G \) convolution is:
    \ [(F * G) (n-) = \ sum_ {d | n} d ^ 2 \ phi (d) g ([\ frac nd]) \]
  • To here, it is not very easy to determine \ (g \) do? If so \ (G = ID \) , will find \ (d ^ 2 \) is got of Jesus. Then \ (F \) and \ (G \) convolution is:
    \ [(F * G) (n-) = \ sum_ {D | D ^ n-2} \ Phi (D) \ FRAC Nd \ Nd = FRAC \ sum_ {d | n} \ phi (d) n ^ 2 = n ^ 2 \ sum_ {d | n} \ phi (d) = n ^ 3 \]

    \ (\ SUM \ limits_ {D | n-} = \ Phi (D) = D \) , to give about n-number to obtain a sum of the Euler function is n, which is commonly used conclusion! ! !

  • Du convolution into the above teachings sieve, can be obtained:
    \ [S (n-) = \ sum_ {I}. 1 = 3- ^ Ni ^ \ sum_ {2} = I ^ ng (I) S ([\ frac ni]) \]

  • From primary Mathematical Olympiad can \ (O (1) \) to obtain \ (i ^ 3 \) prefix and then sieve Du teach written on it A! !

Precautions

  • In the calculation of \ (i ^ 3, i ^ 2 \) prefix and will overflow to count the multiplicative inverse. Further, \ (I \) may be larger than the modulus, the modulo should first recalculation

to sum up

  • In fact, when Du teach sieve find \ (g (x) \) , they often pay more attention \ (f * g \) prefix and good demand of Dirichlet convolution, usually both convolution is \ (\ epsilon \) or \ (the above mentioned id \) . So now a need to find \ (G (X) \) , such that \ (f * g \) is \ (\ Epsilon \) or \ (ID \) . Common Dirichlet convolution see my other blog post stamp here
  • Summarizes several summation formula:
    \ [\ sum_. 1 = {I}. 3 ^ Ni ^ = \ sum_. 1} ^ {n-I = \ sum_. 1} = {J ^ NIJ = \ left (\ {n-FRAC (N- . 1)} 2 \ right) ^ 2 \]
    \ [\ sum_ = {I}. 1 ^ Ni ^ 2 = \ {n-FRAC (n-+. 1) (2N +. 1)}. 6 \]

AC Code

#include<cstdio>
#include<unordered_map>
using namespace std;

const int maxn = 1e7 + 10;

long long n;
int mod;
unordered_map<long long, int> rec;

int ksm(int a, int b)
{
    int ans = 1, base = a % mod;
    while (b)
    {
        if (b & 1)
            ans = 1ll * ans * base % mod;
        base = 1ll * base * base % mod;
        b >>= 1;
    }
    return ans;
}

bool no_prime[maxn];
int prime[maxn], phi[maxn], pre_phi[maxn];
int shai(int n)
{
    int cnt = 0;
    phi[1] = 1;

    for (int i = 2; i <= n; i++)
    {
        if (!no_prime[i])
            prime[++cnt] = i, phi[i] = i - 1;

        for (int j = 1; j <= cnt && prime[j] * i <= n; j++)
        {
            no_prime[prime[j] * i] = 1;
            phi[prime[j] * i] = i % prime[j] == 0 ? phi[i] * prime[j] : phi[i] * (prime[j] - 1);
            if (i % prime[j] == 0) break;
        }
    }

    for (int i = 1; i <= n; i++)
        pre_phi[i] = (pre_phi[i - 1] + 1ll * phi[i] * i % mod * i) % mod;

    return cnt;
}

int inv2;
int inv6;

int pre_x2(long long n)
{
    n %= mod;
    return n * (n + 1) % mod * (2 * n + 1) % mod * inv6 % mod;
}

int pre_x3(long long n)
{
    n %= mod;
    return (n * (n + 1) % mod * inv2 % mod) * (n * (n + 1) % mod * inv2 % mod) % mod;
}

int S(long long n)
{
    if (n <= maxn - 10) return pre_phi[n];
    if (rec[n]) return rec[n];
    int ans = pre_x3(n);
    
    long long l = 2, r;
    while (l <= n)
    {
        r = n / (n / l);
        ans = (ans - (pre_x2(r) - pre_x2(l - 1)) * 1ll * S(n / l)) % mod;
        l = r + 1;
    }
    return rec[n] = ans;
}

void solve()
{
    scanf("%d%lld", &mod, &n);
    shai(maxn - 10);
    inv2 = ksm(2, mod - 2);
    inv6 = ksm(6, mod - 2);

    long long l = 1, r;
    int ans = 0;
    while (l <= n)
    {
        r = n / (n / l);
        int gg = (S(r) - S(l - 1));
        ans = (ans + 1ll * (S(r) - S(l - 1)) * 1ll * pre_x3(n / l)) % mod;
        l = r + 1;
        //printf("%d\n", gg);
    }
    
    printf("%d", (ans % mod + mod) % mod);
}

int main()
{
    solve();
    return 0;
}

Guess you like

Origin www.cnblogs.com/danzh/p/11306100.html