[4450] Luo Gu parents Number (Mobius inversion flood title)

Click here to see the problem surface

Generally meaning of the questions: seeking \ (\ sum_ {I}. 1 = n-^ {} \ sum_ {J} = ^ {m}. 1 [GCD (I, J) == D] \) .

Foreword

The day before met a Mobius inversion problem in the game, because for too long the results did not do a little rusty, no do it.

Today decided to seek Mobius inversion problem mend.

Thus, while the question head is water, and it looks very familiar, seems to have done in similar topics, but I still try to write to write.

Mobius inversion

Consider the formula \ (i, j \) simultaneously divided by \ (D \) , can be obtained:

\[\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac md\rfloor}[gcd(i,j)==1]\]

According to routine, since \ (\ sum_ {P | X} \ MU (P) = [X ==. 1] \) , so we can ([gcd (i, j) == 1] \) \ conversion, then get:

\[\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac md\rfloor}\sum_{p|i,p|j}\mu(p)\]

Enumeration \ (the p-\) , you can get:

\[\sum_{p=1}^{min(\lfloor\frac nd\rfloor,\lfloor\frac md\rfloor)}\mu(p)\lfloor\frac n{dp}\rfloor\lfloor\frac m{dp}\rfloor\]

Which is not difficult to find a time \ (n \) and \ (m \) appears accompanied by a divided by \ (d \) , so we can directly after reading \ (n, m \) each divided by \ (d \) , then you can get a more concise formula:

\[\sum_{p=1}^{min(n,m)}\mu(p)\lfloor\frac n{p}\rfloor\lfloor\frac m{p}\rfloor\]

Considering the demand pretreatment \ (\ mu \) of the process itself is \ (O (n) \) , so here we can directly enumerate \ (the p-\) .

But, as stated in the preface, solving the problem is to regain Mobius inversion, so I hesitate to write a block division.

Code

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000000
#define LL long long
#define min(x,y) ((x)<(y)?(x):(y))
using namespace std;
int n,m,d;
class LinearSieve//线性筛筛μ
{
    private:
        int Pt,P[N+5],mu[N+5];
    public:
        I int operator [] (CI x) {return mu[x];}
        I LinearSieve()
        {
            RI i,j;for(mu[1]=1,i=2;i<=N;++i)
                for(!P[i]&&(mu[P[++Pt]=i]=-1),j=1;j<=Pt&&i*P[j]<=N;++j)
                    if(P[i*P[j]]=1,i%P[j]) mu[i*P[j]]=-mu[i];else break;
            for(i=2;i<=N;++i) mu[i]+=mu[i-1];//统计前缀和
        }
}Mu;
int main()
{
    RI l,r,lim;LL t=0;scanf("%d%d%d",&n,&m,&d),n/=d,m/=d;//一开始直接各除以d
    for(lim=min(n,m),l=1;l<=lim;l=r+1)//除法分块
        r=min(n/(n/l),m/(m/l)),t+=1LL*(Mu[r]-Mu[l-1])*(n/l)*(m/l);
    return printf("%lld",t),0;//输出答案
}

Guess you like

Origin www.cnblogs.com/chenxiaoran666/p/Luogu4450.html