GuGuFishtion(hdu 6390 欧拉函数+莫比乌斯函数)

题目:

GuGuFishtion

 

题意:

Gu(a,b)=\frac{\phi (a,b)}{\phi (a)*\phi (b)} ,已知m,n,p,求 (\sum_{a=1}^{m}\sum_{b=1}^{n}Gu(a,b)) (mod p)  。

 

思路:

欧拉函数性质:\phi (p^{k})=(p-1)*p^{k-1} (p为质数)。

一个数肯定能表示成若干个质数的乘积,因此,设gcd(a,b)=p1^{k1}*p2^{k2}*p3^{k3}*...*pn^{kn}

Gu(a,b)=\frac{\phi (a,b)}{\phi (a)*\phi (b)}

 =\frac{\phi (p1^{2k1}*p2^{2k2}*p3^{2k3}*...*pn^{2kn})}{\phi (p1^{k1}*p2^{k2}*p3^{k3}*...*pn^{kn})^{2}} (其余的项上下展开后都可以约掉,因为它们互质)

=\frac{(p1-1)*(p2-1)*(p3-1)*...*(pn-1)*p1^{2k1-1}*p2^{2k2-1}*p3^{2k3-1}*...*pn^{2kn-1}}{(p1-1)^{2}*(p2-1)^{2}*(p3-1)^{2}*...*(pn-1)^{2}*p1^{2k1-2}*p2^{2k2-2}*p3^{2k3-2}*...*pn^{2kn-2}}

=\frac{p1*p2*p3*..*pn}{(p1-1)*(p2-1)*(p3-1)*...*(pn-1)}

=\frac{p1*p2*p3*...*pn*p1^{k1-1}*p2^{k2-1}*p3^{k3-1}*...*pn^{kn-1}}{(p1-1)*(p2-1)*(p3-1)*...*(pn-1)*p1^{k1-1}*p2^{k2-1}*p3^{k3-1}*...*pn^{kn-1}}

=\frac{p1^{k1}*p2^{k2}*p3^{k3}*...*pn^{kn}}{\phi (p1^{k1}*p2^{k2}*p3^{k3}*...*pn^{kn})}=\frac{gcd(a,b)}{\phi (gcd(a,b))}

a[i]=\frac{i}{\phi (i)}

f(m,n)=\sum_{a=1}^{m}\sum_{b=1}^{n}Gu(a,b)=\sum_{a=1}^{m}\sum_{b=1}^{n}a[gcd(a,b)]

=\sum_{d=1}^{min(m,n)}\sum_{a=1}^{m}\sum_{b=1}^{n}a[d]*[gcd(a,b)==d]

=\sum_{d=1}^{min(m,n)}\sum_{a=1}^{m/d}\sum_{b=1}^{n/d}a[d]*[gcd(a,b)==1]

g(m,n)=\sum_{a=1}^{m}\sum_{b=1}^{n}[gcd(a,b)==1]

=\sum_{a=1}^{m}\sum_{b=1}^{n}\sum_{d|gcd(a,b)}^{ }\mu(d)=\sum_{d=1}^{min(m,n)}\mu (d)*\frac{m}{d}*\frac{n}{d}

 

\mu (d)为莫比乌斯函数,有如下性质:

\sum_{d|n}^{ }\mu (d)=1(当n=1时)

\sum_{d|n}^{ }\mu (d)=0(当n>1时)

当gcd(a,b)==1时,\sum_{d|gcd(a,b)}^{ }\mu(d)=1,当gcd(a,b)!=1时,\sum_{d|gcd(a,b)}^{ }\mu(d)=0,等价于[gcd(a,b)==1]

 

最后一步的转化中,\frac{m}{d}表示在a\in [1,m]中能被d整除的数的个数,\frac{n}{d}表示在b\in [1,n]中能被d整除的数的个数,因此,两者的乘积就表示为在\sum_{a=1}^{m}\sum_{b=1}^{n}累加的过程中满足 d|gcd(a,b) 的情况的个数,因此,最后两个式子等价。

 

\therefore f(m,n)=\sum_{d=1}^{min(m,n)}a[d]*\left ( \sum_{a=1}^{m/d}\sum_{b=1}^{n/d}[gcd(a,b)==1] \right )

=\sum_{d=1}^{min(m,n)}a[d]*g(\frac{m}{d},\frac{n}{d})

 

时间复杂度计算:

a[i]数组,欧拉函数,莫比乌斯函数均能线性预处理。

计算\sum_{d=1}^{min(m,n)}的时间复杂度为O(n);

计算g(\frac{m}{d},\frac{n}{d})的总时间为:

\frac{n}{1}+\frac{n}{2}+\frac{n}{3}+...+\frac{n}{n}=n(1+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{n})=nln(n)+C (C为欧拉常数)

因为有n项,所以每项的平均时间为ln(n)

因此,总时间复杂度为O(nln(n))

 

代码:

因为\phi (i)的值总是小于 i ,所以预处理 max(m,n) 个逆元已经足够了。

#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;

typedef long long ll;

const int MAX = 1e6+10;

ll m,n,mod;
ll prime[MAX],phi[MAX];
int cnt=0;
bool flag[MAX];
int mu[MAX];
ll a[MAX];
ll inv[MAX];
int len;

//预处理欧拉函数phi[ ]和莫比乌斯函数mu[ ]
void init()
{
    memset(flag,false,sizeof(flag));
    phi[1]=1;
    mu[1]=1;
    for(int i=2;i<MAX;i++){
        if(!flag[i]){
            prime[cnt++]=i;
            phi[i]=i-1;
            mu[i] = -1;
        }
        for(int j=0;j<cnt&&i*prime[j]<MAX;j++){
            flag[i*prime[j]]=true;
            if(i%prime[j]==0){
                phi[i*prime[j]]=phi[i]*prime[j];
                mu[i * prime[j]] = 0;
                break;
            }
            else
                phi[i*prime[j]]=phi[i]*(prime[j]-1);
                mu[i * prime[j]] = -mu[i];
        }
    }
}

void gao()
{
    //预处理逆元
    inv[1]=1;
    for(int i=2;i<=len;i++)
        inv[i] = 1LL * inv[mod%i]*(mod-mod/i)%mod;
    //预处理a[ ]数组 ( a[i]=i/phi[i] )
    for(int i=1;i<=len;i++){
        a[i]=1ll*i*inv[phi[i]]%mod;
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    init();
    while(T--)
    {
       scanf("%lld%lld%lld",&m,&n,&mod);
       len=min(m,n);
       gao();
       ll ans=0;
       for(int i=1;i<=len;i++){
          int tmp1=m/i,tmp2=n/i;
          int v=min(tmp1,tmp2);
          //计算g(m/d,n/d)
          ll g=0;
          for(int j=1;j<=v;j++)
            g=(g+1ll*mu[j]*(tmp1/j)*(tmp2/j)+mod)%mod;
          ans=(ans+a[i]*g)%mod;
       }
       printf("%lld\n",ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值