hdu6390 GuGuFishtion 题解(Mobius反演+欧拉函数+除法分块)

题目:hdu6390.
题目大意:给定 n , m , p n,m,p n,m,p p p p为素数,求:
∑ i = 1 n ∑ j = 1 m ϕ ( i j ) ϕ ( i ) ϕ ( j )    ( m o d    p ) \sum_{i=1}^{n}\sum_{j=1}^{m}\frac{\phi(ij)}{\phi(i)\phi(j)}\,\,(mod\,\,p) i=1nj=1mϕ(i)ϕ(j)ϕ(ij)(modp)

1 ≤ n , m ≤ m i n ( 1 0 6 , p ) , 1 ≤ p ≤ 1 0 9 + 7 1\leq n,m\leq min(10^6,p),1\leq p\leq 10^9+7 1n,mmin(106,p),1p109+7,最多三组数据.

先考虑如何化简 ϕ ( i j ) ϕ ( i ) ϕ ( j ) \frac{\phi(ij)}{\phi(i)\phi(j)} ϕ(i)ϕ(j)ϕ(ij),显然除了 i , j i,j i,j的共有质因子外其它因子都会被约分掉,所以我们先取出共有的部分 g = g c d ( i , j ) g=gcd(i,j) g=gcd(i,j).

考虑把共有部分唯一分解 g = ∏ l = 1 k p l c l g=\prod_{l=1}^{k}p_l^{c_l} g=l=1kplcl,显然最后的答案就会变成:
ϕ ( i j ) ϕ ( i ) ϕ ( j ) = g g ∏ l = 1 k p l − 1 p l = g c d ( i , j ) ϕ ( g c d ( i , j ) ) \frac{\phi(ij)}{\phi(i)\phi(j)}=\frac{g}{g\prod_{l=1}^{k}\frac{p_l-1}{p_l}}=\frac{gcd(i,j)}{\phi(gcd(i,j))} ϕ(i)ϕ(j)ϕ(ij)=gl=1kplpl1g=ϕ(gcd(i,j))gcd(i,j)

这个式子看起来比原来优美多了,所以开始推导:
∑ i = 1 n ∑ j = 1 m ϕ ( i j ) ϕ ( i ) ϕ ( j ) = ∑ i = 1 n ∑ j = 1 m g c d ( i , j ) ϕ ( g c d ( i , j ) ) = ∑ d = 1 m i n ( n , m ) d ϕ ( d ) ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ [ g c d ( i , j ) = 1 ] = ∑ d = 1 m i n ( n , m ) d ϕ ( d ) ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ ∑ t ∣ i ∪ t ∣ j μ ( t ) = ∑ d = 1 m i n ( n , m ) d ϕ ( d ) ∑ t = 1 ⌊ m i n ( n , m ) d ⌋ μ ( t ) ⌊ n d t ⌋ ⌊ m d t ⌋ = ∑ c = 1 m i n ( n , m ) ⌊ n c ⌋ ⌊ m c ⌋ ∑ d ∣ c d ϕ ( d ) μ ( c d ) \sum_{i=1}^{n}\sum_{j=1}^{m}\frac{\phi(ij)}{\phi(i)\phi(j)}\\ =\sum_{i=1}^{n}\sum_{j=1}^{m}\frac{gcd(i,j)}{\phi(gcd(i,j))}\\ =\sum_{d=1}^{min(n,m)}\frac{d}{\phi(d)}\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}[gcd(i,j)=1]\\ =\sum_{d=1}^{min(n,m)}\frac{d}{\phi(d)}\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}\sum_{t|i\cup t|j}\mu(t)\\ =\sum_{d=1}^{min(n,m)}\frac{d}{\phi(d)}\sum_{t=1}^{\left\lfloor\frac{min(n,m)}{d}\right\rfloor}\mu(t)\left\lfloor\frac{n}{dt}\right\rfloor\left\lfloor\frac{m}{dt}\right\rfloor\\ =\sum_{c=1}^{min(n,m)}\left\lfloor\frac{n}{c}\right\rfloor\left\lfloor\frac{m}{c}\right\rfloor\sum_{d|c}\frac{d}{\phi(d)}\mu(\frac{c}{d}) i=1nj=1mϕ(i)ϕ(j)ϕ(ij)=i=1nj=1mϕ(gcd(i,j))gcd(i,j)=d=1min(n,m)ϕ(d)di=1dnj=1dm[gcd(i,j)=1]=d=1min(n,m)ϕ(d)di=1dnj=1dmtitjμ(t)=d=1min(n,m)ϕ(d)dt=1dmin(n,m)μ(t)dtndtm=c=1min(n,m)cncmdcϕ(d)dμ(dc)

我们设 f ( n ) = ∑ d ∣ n d ϕ ( d ) μ ( n d ) f(n)=\sum_{d|n}\frac{d}{\phi(d)}\mu(\frac{n}{d}) f(n)=dnϕ(d)dμ(dn),发现这是个积性函数,可以线性筛:
1. i = 1 i=1 i=1,则 f ( i ) = 1 f(i)=1 f(i)=1.
2. i i i为素数,则 f ( i ) = 1 ϕ ( 1 ) μ ( i ) + i ϕ ( i ) μ ( 1 ) = 1 i − 1 f(i)=\frac{1}{\phi(1)}\mu(i)+\frac{i}{\phi(i)}\mu(1)=\frac{1}{i-1} f(i)=ϕ(1)1μ(i)+ϕ(i)iμ(1)=i11.
3. g c d ( i , p ) = 1 gcd(i,p)=1 gcd(i,p)=1,则 f ( i p ) = f ( i ) f ( p ) f(ip)=f(i)f(p) f(ip)=f(i)f(p).
4.当 p p p为素数且 p ∣ i p|i pi时,先考虑 i = p c i=p^c i=pc的情况:
f ( i p ) = f ( p c + 1 ) = ∑ d ∣ p c + 1 d ϕ ( d ) μ ( p c + 1 d ) = − p c ϕ ( p c ) + p c + 1 ϕ ( p c + 1 ) = − p c ( p − 1 ) p c − 1 + p c + 1 ( p − 1 ) p c = 0 f(ip)=f(p^{c+1})=\sum_{d|p^{c+1}}\frac{d}{\phi(d)}\mu(\frac{p^{c+1}}{d})\\ =-\frac{p^c}{\phi(p^c)}+\frac{p^{c+1}}{\phi(p^{c+1})}\\ =-\frac{p^c}{(p-1)p^{c-1}}+\frac{p^{c+1}}{(p-1)p^c}\\ =0 f(ip)=f(pc+1)=dpc+1ϕ(d)dμ(dpc+1)=ϕ(pc)pc+ϕ(pc+1)pc+1=(p1)pc1pc+(p1)pcpc+1=0

然后我们用除法分块处理一下,就可以做到 O ( T n ) O(Tn) O(Tn)解决这个问题了.

代码如下:

#include<bits/stdc++.h>
  using namespace std;

#define Abigail inline void
typedef long long LL;

const int N=1000000;

int n,m;
LL inv[N+9],mod;

void pre_inv(int n,LL mod){
  inv[1]=1;
  for (int i=2;i<=n;++i)
    inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}

int tp,pr[N+9],b[N+9];
LL f[N+9];

void sieve(int n){
  f[1]=1;tp=0;
  for (int i=2;i<=n;++i) b[i]=1;
  for (int i=2;i<=n;++i){
  	if (b[i]) pr[++tp]=i,f[i]=inv[i-1];
  	for (int j=1;j<=tp&&i*pr[j]<=n;++j){
  	  b[i*pr[j]]=0;
  	  if (i%pr[j]==0){f[i*pr[j]]=0;break;}
  	  f[i*pr[j]]=f[i]*f[pr[j]]%mod;
  	}
  }
}

LL Query(int n,int m){
  LL ans=0;
  for (int l=1,r;l<=n;l=r+1){
  	r=min(n/(n/l),m/(m/l));
  	ans=(ans+(f[r]-f[l-1]+mod)*(n/l)%mod*(m/l))%mod;
  }
  return ans;
}

Abigail into(){
  scanf("%d%d%lld",&n,&m,&mod); 
}

Abigail work(){
  if (n>m) swap(n,m);
  pre_inv(n,mod);
  sieve(n);
  for (int i=1;i<=n;++i){ 
    f[i]+=f[i-1];
    if (f[i]>=mod) f[i]-=mod;
  } 
}

Abigail outo(){
  printf("%lld\n",Query(n,m));
}

int main(){
  int T;
  scanf("%d",&T);
  while (T--){
  	into();
    work();
  	outo();
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值