【Luogu】 P5176 公约数

题目链接

点击打开链接

题目解法

首先证明一个结论: ( i j , i k , j k ) = ( i , j ) ( i , k ) ( j , k ) ( i , j , k ) (ij,ik,jk)=\frac{(i,j)(i,k)(j,k)}{(i,j,k)} (ij,ik,jk)=(i,j,k)(i,j)(i,k)(j,k)
考虑对于 i , j , k i,j,k i,j,k 的质因子 p p p 的次数考虑,假设次数分别为 a , b , c ( a ≤ b ≤ c ) a,b,c(a\le b\le c) a,b,c(abc)
对于右边, ( i , j , k ) = a (i,j,k)=a (i,j,k)=a ( i , j ) = a , ( i , k ) = a , ( j , k ) = b (i,j)=a,(i,k)=a,(j,k)=b (i,j)=a,(i,k)=a,(j,k)=b,所以 ( i , j ) ( i , k ) ( j , k ) ( i , j , k ) = a b \frac{(i,j)(i,k)(j,k)}{(i,j,k)}=ab (i,j,k)(i,j)(i,k)(j,k)=ab
对于左边, i j = a b ,    i k = a c ,    j k = b c ij=ab,\;ik=ac,\;jk=bc ij=ab,ik=ac,jk=bc,所以 ( i j , i k , j k ) = a b (ij,ik,jk)=ab (ij,ik,jk)=ab
所以 左边 = 右边
可以推广到任意数的情况

所以
A n s = ∑ i = 1 n ∑ j = 1 m ∑ k = 1 p ( i , j ) ( i , k ) ( j , k ) ( i , j , k ) ∗ ( i , j , k ) ∗ ( ( i , j ) ( i , k ) ( j , k ) + ( i , k ) ( i , j ) ( j , k ) + ( j , k ) ( i , j ) ( i , k ) ) Ans=\sum^{n}_{i=1}\sum^{m}_{j=1}\sum^{p}_{k=1}\frac{(i,j)(i,k)(j,k)}{(i,j,k)}*(i,j,k)*\left(\frac{(i,j)}{(i,k)(j,k)}+\frac{(i,k)}{(i,j)(j,k)}+\frac{(j,k)}{(i,j)(i,k)}\right) Ans=i=1nj=1mk=1p(i,j,k)(i,j)(i,k)(j,k)(i,j,k)((i,k)(j,k)(i,j)+(i,j)(j,k)(i,k)+(i,j)(i,k)(j,k))
= ∑ i = 1 n ∑ j = 1 m ∑ k = 1 p ( i , j ) ( i , k ) ( j , k ) ∗ ( ( i , j ) ( i , k ) ( j , k ) + ( i , k ) ( i , j ) ( j , k ) + ( j , k ) ( i , j ) ( i , k ) ) =\sum^{n}_{i=1}\sum^{m}_{j=1}\sum^{p}_{k=1}(i,j)(i,k)(j,k)*\left(\frac{(i,j)}{(i,k)(j,k)}+\frac{(i,k)}{(i,j)(j,k)}+\frac{(j,k)}{(i,j)(i,k)}\right) =i=1nj=1mk=1p(i,j)(i,k)(j,k)((i,k)(j,k)(i,j)+(i,j)(j,k)(i,k)+(i,j)(i,k)(j,k))
= ∑ i = 1 n ∑ j = 1 m ∑ k = 1 p ( i , j ) 2 + ( i , k ) 2 + ( j , k ) 2 =\sum^{n}_{i=1}\sum^{m}_{j=1}\sum^{p}_{k=1}(i,j)^2+(i,k)^2+(j,k)^2 =i=1nj=1mk=1p(i,j)2+(i,k)2+(j,k)2
考虑对于 ( i , j ) 2 (i,j)^2 (i,j)2 的项只与 i , j i,j i,j 有关,所以考虑计算它的系数
所以 A n s = p ∗ ∑ i = 1 n ∑ j = 1 m ( i , j ) 2 + m ∗ ∑ i = 1 n ∑ k = 1 p ( i , k ) 2 + n ∗ ∑ j = 1 m ∑ k = 1 p ( j , k ) 2 Ans=p*\sum^{n}_{i=1}\sum^{m}_{j=1}(i,j)^2+m*\sum^{n}_{i=1}\sum^{p}_{k=1}(i,k)^2+n*\sum^{m}_{j=1}\sum^{p}_{k=1}(j,k)^2 Ans=pi=1nj=1m(i,j)2+mi=1nk=1p(i,k)2+nj=1mk=1p(j,k)2

考虑单独计算 ∑ i = 1 n ∑ j = 1 m ( i , j ) 2 \sum^{n}_{i=1}\sum^{m}_{j=1}(i,j)^2 i=1nj=1m(i,j)2,其他的同理
根据莫比乌斯反演,考虑枚举 d d d
∑ i = 1 n ∑ j = 1 m ( i , j ) 2 \sum^{n}_{i=1}\sum^{m}_{j=1}(i,j)^2 i=1nj=1m(i,j)2
= ∑ d = 1 n d 2 ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ n d ⌋ [ ( i , j ) = 1 ] =\sum_{d=1}^{n}d^2\sum^{\lfloor\frac{n}{d}\rfloor}_{i=1}\sum^{\lfloor\frac{n}{d}\rfloor}_{j=1}[(i,j)=1] =d=1nd2i=1dnj=1dn[(i,j)=1]
接下来就是套路的莫比乌斯反演
最终可以化的答案为 ∑ T = 1 n ⌊ n T ⌋ ⌊ m T ⌋ ∑ k ∣ T k 2 ∗ μ ( T k ) \sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum_{k|T}k^2*\mu(\frac{T}{k}) T=1nTnTmkTk2μ(kT)
其中前半部分可以数论分块做,可以做到 O ( n ) O(\sqrt n) O(n )
考虑如何将 ∑ k ∣ T k 2 ∗ μ ( T k ) \sum_{k|T}k^2*\mu(\frac{T}{k}) kTk2μ(kT) 在线性的时间内预处理出
f ( n ) = n 2 ,    g ( n ) = μ ( n ) ,    h ( n ) = ∑ k ∣ n k 2 ∗ μ ( n k ) f(n)=n^2,\;g(n)=\mu(n),\;h(n)=\sum_{k|n}k^2*\mu(\frac{n}{k}) f(n)=n2,g(n)=μ(n),h(n)=knk2μ(kn)
f ∗ g = h f*g=h fg=h
因为 f f f g g g 都是积性函数,所以卷积出来的 h h h 也是积性函数
考虑线性筛
现在需要解决 h ( p k ) ( k > 1 ) h(p^k)(k>1) h(pk)(k>1) 的情况如何递推
h ( p ) = ∑ k ∣ p k 2 ∗ μ ( p k ) = p 2 − 1 h(p)=\sum_{k|p}k^2*\mu(\frac{p}{k})=p^2-1 h(p)=kpk2μ(kp)=p21
h ( p k ) = ∑ k ∣ p k 2 ∗ μ ( p k ) = μ ( p k ) + p 2 ∗ μ ( p k − 1 ) + . . . + p 2 ( k − 1 ) ∗ μ ( p ) + p 2 k ∗ μ ( 1 ) h(p^k)=\sum_{k|p}k^2*\mu(\frac{p}{k})=\mu(p^k)+p^2*\mu(p^{k-1})+...+p^{2(k-1)}*\mu(p)+p^{2k}*\mu(1) h(pk)=kpk2μ(kp)=μ(pk)+p2μ(pk1)+...+p2(k1)μ(p)+p2kμ(1)
考虑 μ ( p k ) ( k > 1 ) = 0 \mu(p^k)(k>1)=0 μ(pk)(k>1)=0
所以 h ( p k ) = p 2 k − p 2 ( k − 1 ) = p 2 ∗ h ( p k − 1 ) h(p^k)=p^{2k}-p^{2(k-1)}=p^2*h(p^{k-1}) h(pk)=p2kp2(k1)=p2h(pk1)

时间复杂度 O ( n + T n ) O(n+T\sqrt n) O(n+Tn )

#include 
using namespace std;
typedef long long LL;
const int N(20000100),P(1e9+7);
int h[N],pr[N/10],cnt;
bool vis[N];
inline int read(){
	int FF=0,RR=1;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
	for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
	return FF*RR;
}
void init(int n){
	h[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]) pr[++cnt]=i,h[i]=((LL)i*i%P-1+P)%P;
		for(int j=1;j<=cnt&&i<=n/pr[j];j++){
			vis[pr[j]*i]=1;
			if(i%pr[j]==0){
				h[pr[j]*i]=(LL)h[i]*pr[j]%P*pr[j]%P;
				break;
			}
			h[pr[j]*i]=(LL)h[i]*h[pr[j]]%P;
		}
	}
	for(int i=2;i<=n;i++) h[i]=(h[i-1]+h[i])%P;
}
int ask(int n,int m){
	int t=min(n,m),res=0;
	for(int i=1,j;i<=t;i=j+1){
		j=min(n/(n/i),m/(m/i));
		res=(res+(LL)(n/i)*(m/i)%P*(h[j]-h[i-1]+P)%P)%P;
	}
	return res;
}
void work(){
	int n=read(),m=read(),p=read();
	printf("%d\n",(LL)((LL)p*ask(n,m)%P+(LL)m*ask(n,p)%P+(LL)n*ask(m,p)%P)%P);
}
int main(){
	init(2e7); 
	int T=read();
	while(T--) work();
	return 0;
}

你可能感兴趣的:(Luogu,算法)