[BZOJ 2820] YY of gcd (+ Mobius inversion block number theory)

[BZOJ 2820] YY of gcd (+ Mobius inversion block number theory)

Face questions

Given N, M, ask \ (1 \ leq x \ leq N, 1 \ leq y \ leq M \) and gcd (x, y) is the number of primes (x, y). q group inquiry

analysis

All we ask is

\ [\ sum_ {P \ P} in \ sum_. 1} ^ {n-I = \ sum_. 1} = {J ^ m [GCD (I, J) = P] \] (uppercase P represents a set of prime numbers)

The \ (kgcd (I, J) = GCD (Ki, kJ) \) ,

\[原式=\sum_{p \in P} \sum_{i=1}^{\lfloor n/p \rfloor} \sum_{j=1}^{\lfloor m/p \rfloor} [gcd(i,j)=1]\]

According to a further conclusion Möbius inversion in the usual (see proof BZOJ 2301 ) \ [\ sum_. 1} ^ {n-I = \ sum_. 1} = {J ^ m [GCD (I, J) =. 1] = \ sum_ {d = 1} ^ {min (n, m)} \ mu (d) \ lfloor \ frac {n} {d} \ rfloor \ lfloor \ frac {m} {d} \ rfloor \]

\[原式=\sum_{p \in P} \sum_{d=1}^{min( \lfloor n/p \rfloor, \lfloor m/p \rfloor)} \mu(d) \lfloor \frac{n}{pd} \rfloor \lfloor \frac{m}{pd} \rfloor \]

Order \ (T = PD \) , then \ (d = \ frac {T } {p} \)

Changing the order of summation, \ [original formula = \ sum_ {T = 1} ^ {min (n, m)} \ sum_ {p | t \ \ cap \ p \ in P} \ lfloor \ frac {n} {T } \ rfloor \ lfloor \ frac { m} {T} \ rfloor \ mu (\ frac {T} {p}) \]

\[=\sum_{T=1}^{min(n,m)}) \lfloor \frac{n}{T} \rfloor \lfloor \frac{m}{T} \rfloor \sum_{p|t \ \cap \ p \in P} \mu(\frac{T}{p})\]

\(g(n)=\sum_{p|n \ \cap \ p \in P } \mu(\frac{n}{p})\)

\[原式=\sum_{T=1}^{min(n,m)}) \lfloor \frac{n}{T} \rfloor \lfloor \frac{m}{T} \rfloor g(T)\]

The front part of number theory can solve the block, considering how quickly obtain \ (g (T) \)

For each prime number \ (the p-\) , we start from the 1 enum \ (J \) , and ensure that \ (jp \ the n-Leq \) , followed by \ (\ mu (j) \ ) update \ (g (jp ) \) values.

Because of \ (. 1 /. 1. 1 + / 2 +. 1 /. 3. 1 + ... + / n-= O (logN) \) , each update complexity is amortized \ (O (\ log n) \) , and 1 ~ n and prime with a probability of about \ (\ frac {n} { \ ln n} \) th, the pre-function g total time complexity is \ (O (n) \)

The total time complexity \ (O (n + q \ sqrt n) \)

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 10000000
using namespace std;
typedef long long ll;
int t,n,m;
int cnt;
int prime[maxn+5];
bool vis[maxn+5];
int mu[maxn+5];
ll g[maxn+5];
ll sumg[maxn+5];
void sieve(int n){
    mu[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i]){
            mu[i]=-1;
            prime[++cnt]=i;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0){
                mu[i*prime[j]]=0;
                break;
            }else mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=1;i<=cnt;i++){
        for(int j=1;j*prime[i]<=n;j++){
            g[prime[i]*j]+=mu[j];
        }
    }
    for(int i=1;i<=n;i++){
        sumg[i]=sumg[i-1]+g[i];
    }
} 

int cas;
ll calc(int n,int m){
    int nn=min(n,m);
    ll ans=0;
    for(int l=1,r;l<=nn;l=r+1){
        r=min(n/(n/l),m/(m/l));
        ans+=(sumg[r]-sumg[l-1])*(n/l)*(m/l);
    }
    return ans;
}
int main(){
    sieve(maxn);
    scanf("%d",&cas);
    while(cas--){
        scanf("%d %d",&n,&m);
        printf("%lld\n",calc(n,m));
    }
}

Guess you like

Origin www.cnblogs.com/birchtree/p/11366642.html