P2257 YY的GCD

H y p e r l i n k Hyperlink Hyperlink

https://www.luogu.org/problem/P2257


D e s c r i p t i o n Description Description

∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) ∈ p r i m e ] \sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)\in prime] i=1nj=1m[gcd(i,j)prime]

n , m ≤ 1 0 7 , T ≤ 1 0 4 n,m\leq 10^7,T\leq 10^4 n,m107,T104


S o l u t i o n Solution Solution

先枚举素数

∑ k = 1 n ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = k ] ( k ∈ p r i m e ) \sum_{k=1}^n\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k](k\in prime) k=1ni=1nj=1m[gcd(i,j)=k](kprime)

同时除以 k k k

∑ k = 1 n ∑ i = 1 n / k ∑ j = 1 m / k [ g c d ( i , j ) = 1 ] ( k ∈ p r i m e ) \sum_{k=1}^n\sum_{i=1}^{n/k}\sum_{j=1}^{m/k}[gcd(i,j)=1](k\in prime) k=1ni=1n/kj=1m/k[gcd(i,j)=1](kprime)

我们知道莫比乌斯函数的性质 ∑ d ∣ n μ ( d ) = [ n = 1 ] \sum_{d|n}\mu(d)=[n=1] dnμ(d)=[n=1]
把这个 n n n换成 g c d ( i , j ) gcd(i,j) gcd(i,j)

[ g c d ( i , j ) = 1 ] = ∑ d ∣ g c d ( i , j ) μ ( d ) [gcd(i,j)=1]=\sum_{d|gcd(i,j)}\mu(d) [gcd(i,j)=1]=dgcd(i,j)μ(d)

丢进原式

∑ k = 1 n ∑ i = 1 n / k ∑ j = 1 m / k ∑ d ∣ g c d ( i , j ) μ ( d ) ( k ∈ p r i m e ) \sum_{k=1}^n\sum_{i=1}^{n/k}\sum_{j=1}^{m/k}\sum_{d|gcd(i,j)}\mu(d)(k\in prime) k=1ni=1n/kj=1m/kdgcd(i,j)μ(d)(kprime)

然后我们阔以枚举 d d d,把 d d d提出来,因为 d ∣ g c d ( i , j ) d|gcd(i,j) dgcd(i,j),所以 i , j i,j i,j都是 d d d的倍数,自然这范围中是 d d d倍数的有 ⌊ i 的 上 限 d ⌋ × ⌊ j 的 上 限 d ⌋ \lfloor \dfrac{i的上限}d\rfloor\times \lfloor \dfrac{j的上限}d\rfloor di×dj个,即 ⌊ ⌊ n k ⌋ d ⌋ × ⌊ ⌊ m k ⌋ d ⌋ = ⌊ n k d ⌋ × ⌊ m k d ⌋ \lfloor\dfrac{\lfloor\dfrac nk\rfloor}d\rfloor\times \lfloor \dfrac{\lfloor\dfrac m k\rfloor}d\rfloor=\lfloor\dfrac n{kd}\rfloor\times \lfloor \dfrac m{kd}\rfloor dkn×dkm=kdn×kdm

于是原式=

∑ k = 1 n ∑ d = 1 n / k μ ( d ) × ⌊ n k d ⌋ × ⌊ m k d ⌋ \sum_{k=1}^n\sum_{d=1}^{n/k}\mu(d)\times \lfloor\dfrac n{kd}\rfloor\times \lfloor \dfrac m{kd}\rfloor k=1nd=1n/kμ(d)×kdn×kdm

T = k d T=kd T=kd,扔进去

∑ T = 1 n ⌊ n T ⌋ × ⌊ m T ⌋ ∑ k ∣ T , k ∈ p r i m e μ ( T k ) \sum_{T=1}^n\lfloor\dfrac nT\rfloor\times \lfloor \dfrac mT\rfloor\sum_{k|T,k\in prime}\mu(\dfrac T k) T=1nTn×TmkT,kprimeμ(kT)

后面那坨 k k k就是 T T T的质因子,是可以预处理的!!!

于是对于每一个质数 k k k,对于它的倍数 T T T,都加上一个 μ ( T k ) \mu(\dfrac Tk) μ(kT)

处理一下前缀和,打个整除分块就A了啦

时间复杂度: O ( n l o g n + T n ) O(nlogn+T\sqrt n) O(nlogn+Tn )


C o d e Code Code

#include
#include
#include
#define N 10000000
#define LL long long
using namespace std;
LL mu[N+10];int prime[N>>3],m,f[N+10],sum[N+10],t,x,y;
bool vis[N+10];
inline LL read()
{
	LL f=0,d=1;char c; 
	while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
inline LL solve(int a,int b)
{
	LL res=0;
	for(register int l=1,r=0;l<=a;l=r+1)
	{
		r=min(a/(a/l),b/(b/l));
		res+=(LL)(sum[r]-sum[l-1])*(LL)(a/l)*(b/l);
	}
	return res;
}
signed main()
{
	mu[1]=1;
	for(register int i=2;i<=N;i++)
	{
		if(vis[i]==0) {prime[++m]=i;mu[i]=-1;}
		for(register int j=1;j<=m&&prime[j]*i<=N;j++)
		{
			vis[prime[j]*i]=true;
			if(i%prime[j]==0) break;
			mu[prime[j]*i]=-mu[i];
		}
	}
	for(register int i=1;i<=m;i++)
	 for(register int j=1;prime[i]*j<=N;j++)
	  f[j*prime[i]]+=mu[j];
	for(register int i=1;i<=N;i++) sum[i]=sum[i-1]+f[i];
	for(t=read();t--;)
	{
		x=read();y=read();
		if(x>y) x^=y,y=x^y,x^=y;
		printf("%lld\n",solve(x,y));
	}
}

你可能感兴趣的:(莫比乌斯反演,数论)