Loading

P5176 公约数

P5176 公约数

说在前面的话:

这题后面的线性筛和 P4449 于神之怒加强版 很像,建议这两道题连着做,巩固一下非常规函数线性筛顺便水个双倍经验。但是网上于神之怒的题解都过于简略(我比较菜),看不懂,做于神之怒的时候很痛苦,因此本文线性筛的过程尽量详细写,让初学者看懂,看不懂欢迎在评论区提问,NOIP前应该能做到1天内回复。

\[\sum_{i=1}^n\sum_{j=1}^m\sum_{k=1}^p\gcd(i\cdot j,i\cdot k,j\cdot k)\times \gcd(i,j,k)\times \left(\frac{\gcd(i,j)}{\gcd(i,k)\times \gcd(j,k)}+\frac{\gcd(i,k)}{\gcd(i,j)\times \gcd(j,k)}+\frac{\gcd(j,k)}{\gcd(i,j)\times \gcd(i,k)}\right) \]

那个 \(\gcd(ij,jk,ki)\) 一看就是要化掉的。

显然应该从质因子的幂次入手,设 \(i=p^a,j=p^b,k=p^c\)

那么 \(p\)\(\gcd(ij,jk,,ki)\) 的贡献就是 \(p^{\min(a+b,b+c,c+a)}\)

考虑构造一个东西来表示 \(\min(a+b,b+c,c+a)\) 。不妨 \(a\le b\le c\) (显然排序不会影响结果)

\(\min(a+b,b+c,c+a)=a+b=\min(a,b)+\min(b,c)+\min(a,c)-\min(a,b,c)\)

转成 \(\gcd\) 的写法就是 \(\gcd(ij,jk,ki)=\dfrac{\gcd(i,j)\gcd(j,k)\gcd(k,i)}{\gcd(i,j,k)}\)

带回原式发现良心出题人非常非常非常良心地帮你约掉了 \(\gcd(i,j,k)\) 这种三元 \(\gcd\) 以及所有分母

化简一下,原式\(=\sum\limits_{i=1}^{A}\sum\limits_{j=1}^{B}\sum\limits_{k=1}^{C}\gcd(i,j)^2+\gcd(j,k)^2+\gcd(k,i)^2\)

发现凉心出题人非常非常非常凉心把 \(\gcd\) 平方了。

原式显然可以分成三部分算。

先算

\[\sum_{i=1}^{A}\sum_{j=1}^{B}\sum_{i=1}^{C}\gcd(i,j)^2\\ =C\sum_{i=1}^{A}\sum_{j=1}^{B}\gcd(i,j)^2\\ =C\sum_{d=1}^{A} \sum_{i=1}^{A}\sum_{j=1}^{B}[\gcd(i,j)==d]d^2\\ =C\sum_{d=1}^{A}d^2\sum_{i=1}^{\frac{A}{d}}\sum_{j=1}^{\frac{B}{d}}[\gcd(i,j)==1]\\ =C\sum_{d=1}^{A}d^2\sum_{i=1}^{\frac{A}{d}}\sum_{j=1}^{\frac{B}{d}}\sum_{x|\gcd(i,j)}\mu(x)\\ =C\sum_{d=1}^{A}d^2\sum_{x=1}^{\frac{A}{d}}\mu(x)\dfrac{A}{dx}\dfrac{B}{dx}\\ =C\sum_{d=1}^{A}d^2\sum_{T=1,d|T}^{A}\mu(\dfrac{T}{d})\dfrac{A}{T}\dfrac{B}{T}\\ =\sum_{T=1}^{A}\dfrac{A}{T}\dfrac{B}{T}\sum_{d|T}d^2\mu(\dfrac{T}{d}) \]

现在的问题在于 \(f(T)=\sum_{d|T}d^2\mu(\dfrac{T}{d})\) ,这个东西一出来就可以 \(O(\sqrt{n})\) 整除分块了。

仔细观察发现这是个积性函数,可以线性筛, \(2e7\) 怕他啥(\(\color{black}{\texttt{c}}\color{red}{\texttt{yn2006}}\) \(O(n\ln n)\) 暴力筛都过去了)。

\(p\in prime\) ,则

\[f(p)=\mu(1)\times p^2+mu(p)\times 1^2=p^2-1\\ \]

接下去处理掉 \(p|i\) 的情况就可以线性筛了。

\(x\)\(p\)\(T\) 中的最高幂次

发掘 \(\mu\) 的性质,当且仅当 \(d=p^x\)\(d=p^{x-1}\) 时有贡献(\(\mu(\dfrac{T}{d})!=0\))。

带入得

\(f(p^x)=p^{2x}-p^{2(x-1)}\)

\(f(p^{x+1})=p^{2(x+1)}-p^{2x}=p^2(p^{2x}-p^{2(x-1)})=p^2f(p^x)\)

\(\therefore f(ip)=f(i)\times p^2(p|i)\) ,综合如下:

\[f(T)= \begin{cases} T^2-1(T\in \mathcal{prime})\\ f(i)*p^2(p|i)\\ f(i)*f(p)(otherwise) \end{cases} \]

可以线性筛了

提供一组大样例以供调试

Input
1
10000000 5000000 20000000
Output
913785109
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define pb(x) push_back(x)
#define mkp(x,y) make_pair(x,y)
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
//char buf[1<<21],*p1=buf,*p2=buf;
inline int read() {
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch))x=x*10+(ch^48),ch=getchar();
	return x*f;
}
const int N=20000005;
const int mod=1000000007;
int A,B,C;
int pri[N/10],cnt,s[N];
bool vis[N];
void Sieve(const int N=20000000){
	s[1]=1;
	for(int i=2;i<=N;++i){
		if(!vis[i])pri[++cnt]=i,s[i]=1ll*i*i%mod-1;
		for(int j=1;j<=cnt&&i*pri[j]<=N;++j){
			vis[i*pri[j]]=1;
			if(i%pri[j]==0){s[i*pri[j]]=1ll*s[i]*pri[j]%mod*pri[j]%mod;break;}
			s[i*pri[j]]=1ll*s[i]*s[pri[j]]%mod;
		}
	}
	for(int i=1;i<=N;++i)s[i]=(s[i]+s[i-1])%mod;
}
int f(int A,int B,int C){
	int res=0;
	for(int l=1,r,mx=min(A,B);l<=mx;l=r+1){
		r=min(A/(A/l),B/(B/l));
		res=(res+1ll*(A/l)*(B/l)%mod*(s[r]-s[l-1])%mod)%mod;
	}
	return 1ll*res*C%mod;
}
signed main(){
	Sieve();
	for(int T=read();T;--T){
		A=read(),B=read(),C=read();
		printf("%d\n",(((f(A,B,C)+f(B,C,A))%mod+f(C,A,B))%mod+mod)%mod);
	}
}
posted @ 2020-10-03 14:27  zzctommy  阅读(128)  评论(0编辑  收藏  举报