『题解』Luogu-P5176 公约数

P5176 公约数

Description

  • 多测, T T T 组数据。

  • 给定 n , m , p n, m, p n,m,p,请求出
    [ ∑ i = 1 n ∑ j = 1 m ∑ k = 1 p gcd ⁡ ( i j , i k , j k ) ⋅ gcd ⁡ ( i , j , k ) ⋅ ( gcd ⁡ ( i , j ) gcd ⁡ ( i , k ) ⋅ gcd ⁡ ( j , k ) + gcd ⁡ ( i , k ) gcd ⁡ ( i , j ) ⋅ gcd ⁡ ( j , k ) + gcd ⁡ ( j , k ) gcd ⁡ ( i , j ) ⋅ gcd ⁡ ( i , k ) ) ]   m o d   ( 1 0 9 + 7 ) \left[ \sum_{i = 1}^n \sum_{j = 1}^m \sum_{k = 1}^p \gcd(ij, ik, jk)\cdot \gcd(i, j, k)\cdot \left(\dfrac{\gcd(i, j)}{\gcd(i, k)\cdot \gcd(j, k)} + \dfrac{\gcd(i, k)}{\gcd(i, j)\cdot \gcd(j, k)} + \dfrac{\gcd(j, k)}{\gcd(i, j)\cdot \gcd(i, k)} \right) \right] \bmod (10^9 + 7) [i=1nj=1mk=1pgcd(ij,ik,jk)gcd(i,j,k)(gcd(i,k)gcd(j,k)gcd(i,j)+gcd(i,j)gcd(j,k)gcd(i,k)+gcd(i,j)gcd(i,k)gcd(j,k))]mod(109+7)

  • T ≤ 1 0 3 , n , m , p , ≤ 2 × 1 0 7 T\le 10^3, n, m, p, \le 2\times 10^7 T103,n,m,p,2×107

Solution

引理:
gcd ⁡ ( i j , i k , j k ) = gcd ⁡ ( i , j ) gcd ⁡ ( i , k ) gcd ⁡ ( j , k ) gcd ⁡ ( i , j , k ) \gcd(ij,ik,jk) = \dfrac{\gcd(i,j)\gcd(i,k)\gcd(j,k)}{\gcd(i,j,k)} gcd(ij,ik,jk)=gcd(i,j,k)gcd(i,j)gcd(i,k)gcd(j,k)

证明:

只需证任意一种质因数 p p p 的次数相等即可,因为若两个数的任意质因数的次数都相等,则这两个数相等。

i , j , k i, j, k i,j,k 分别含 a , b , c a, b, c a,b,c 个质因数 p p p,不妨设 a ≤ b ≤ c a\le b\le c abc

gcd ⁡ ( i k , i k , j k ) \gcd(ik, ik, jk) gcd(ik,ik,jk) 中的质因数 p p p 的次数为 min ⁡ ( a + b , a + c , b + c ) = a + b \min(a + b, a + c, b + c) = a + b min(a+b,a+c,b+c)=a+b

gcd ⁡ ( i , j ) gcd ⁡ ( i , k ) gcd ⁡ ( j , k ) gcd ⁡ ( i , j , k ) \dfrac{\gcd(i,j)\gcd(i,k)\gcd(j,k)}{\gcd(i,j,k)} gcd(i,j,k)gcd(i,j)gcd(i,k)gcd(j,k) 中的质因数 p p p 的次数为 min ⁡ ( a , b ) + min ⁡ ( a , c ) + min ⁡ ( b , c ) − min ⁡ ( a , b , c ) = a + a + b − a = a + b \min(a, b) + \min(a, c) + \min(b, c) - \min(a, b, c) = a + a + b - a = a + b min(a,b)+min(a,c)+min(b,c)min(a,b,c)=a+a+ba=a+b

所以这两个数的质因数 p p p 的次数相等。


所以
a n s = ∑ i = 1 n ∑ j = 1 m ∑ k = 1 p gcd ⁡ ( i , j ) gcd ⁡ ( i , k ) gcd ⁡ ( j , k ) gcd ⁡ ( i , j , k ) ⋅ gcd ⁡ ( i , j , k ) ⋅ ( gcd ⁡ ( i , j ) gcd ⁡ ( i , k ) ⋅ gcd ⁡ ( j , k ) + gcd ⁡ ( i , k ) gcd ⁡ ( i , j ) ⋅ gcd ⁡ ( j , k ) + gcd ⁡ ( j , k ) gcd ⁡ ( i , j ) ⋅ gcd ⁡ ( i , k ) ) = ∑ i = 1 n ∑ j = 1 m ∑ k = 1 p gcd ⁡ ( i , j ) 2 + gcd ⁡ ( i , k ) 2 + gcd ⁡ ( j , k ) 2 = p ∑ i = 1 n ∑ j = 1 m gcd ⁡ ( i , j ) 2 + m ∑ i = 1 n ∑ k = 1 p gcd ⁡ ( i , k ) 2 + n ∑ j = 1 m ∑ k = 1 p gcd ⁡ ( j , k ) 2 \begin{aligned} ans & = \sum_{i = 1}^n \sum_{j = 1}^m \sum_{k = 1}^p \dfrac{\gcd(i,j)\gcd(i,k)\gcd(j,k)}{\gcd(i,j,k)} \cdot \gcd(i, j, k)\cdot \left(\dfrac{\gcd(i, j)}{\gcd(i, k)\cdot \gcd(j, k)} + \dfrac{\gcd(i, k)}{\gcd(i, j)\cdot \gcd(j, k)} + \dfrac{\gcd(j, k)}{\gcd(i, j)\cdot \gcd(i, k)} \right) \\ & = \sum_{i = 1}^n \sum_{j = 1}^m \sum_{k = 1}^p \gcd(i, j)^2 + \gcd(i, k)^2 + \gcd(j, k)^2 \\ & = p \sum_{i = 1}^n \sum_{j = 1}^m \gcd(i, j)^2 + m \sum_{i = 1}^n \sum_{k = 1}^p \gcd(i, k)^2 + n \sum_{j = 1}^m \sum_{k = 1}^p \gcd(j, k)^2 \end{aligned} ans=i=1nj=1mk=1pgcd(i,j,k)gcd(i,j)gcd(i,k)gcd(j,k)gcd(i,j,k)(gcd(i,k)gcd(j,k)gcd(i,j)+gcd(i,j)gcd(j,k)gcd(i,k)+gcd(i,j)gcd(i,k)gcd(j,k))=i=1nj=1mk=1pgcd(i,j)2+gcd(i,k)2+gcd(j,k)2=pi=1nj=1mgcd(i,j)2+mi=1nk=1pgcd(i,k)2+nj=1mk=1pgcd(j,k)2

f ( n , m ) = ∑ i = 1 n ∑ j = 1 m gcd ⁡ ( i , j ) 2 f(n, m) = \sum_{i = 1}^n \sum_{j = 1}^m \gcd(i, j)^2 f(n,m)=i=1nj=1mgcd(i,j)2

a n s = p f ( n , m ) + m f ( n , p ) + n f ( m , p ) ans = p f(n, m) + m f(n, p) + n f(m, p) ans=pf(n,m)+mf(n,p)+nf(m,p)
f ( n , m ) f(n, m) f(n,m)(不妨设 n ≤ m n\le m nm
f ( n , m ) = ∑ i = 1 n ∑ j = 1 m gcd ⁡ ( i , j ) 2 = ∑ d = 1 n ∑ i = 1 n ∑ j = 1 m d 2 [ gcd ⁡ ( i , j ) = d ] = ∑ d = 1 n d 2 ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ [ gcd ⁡ ( i , j ) = 1 ] = ∑ d = 1 n d 2 ∑ k = 1 ⌊ n d ⌋ μ ( k ) ⌊ n d k ⌋ ⌊ m d k ⌋ = ∑ T = 1 n ⌊ n T ⌋ ⌊ m T ⌋ ∑ k ∣ T μ ( k ) ( T k ) 2 = ∑ T = 1 n ⌊ n T ⌋ ⌊ m T ⌋ ( μ ∗ Id ⁡ 2 ) ( T ) \begin{aligned} f(n, m) & = \sum_{i = 1}^n \sum_{j = 1}^m \gcd(i, j)^2 \\ & = \sum_{d = 1}^n \sum_{i = 1}^n \sum_{j = 1}^m d^2 [\gcd(i, j) = d] \\ & = \sum_{d = 1}^n d^2 \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}^n d^2 \sum_{k = 1}^{\left\lfloor\frac{n}{d}\right\rfloor} \mu(k) \left\lfloor\dfrac{n}{dk}\right\rfloor \left\lfloor\dfrac{m}{dk}\right\rfloor \\ & = \sum_{T = 1}^n \left\lfloor\dfrac{n}{T}\right\rfloor \left\lfloor\dfrac{m}{T}\right\rfloor \sum_{k \mid T} \mu(k) \left(\dfrac{T}{k} \right)^2 \\ & = \sum_{T = 1}^n \left\lfloor\dfrac{n}{T}\right\rfloor \left\lfloor\dfrac{m}{T}\right\rfloor (\mu * \operatorname{Id}_2)(T) \end{aligned} f(n,m)=i=1nj=1mgcd(i,j)2=d=1ni=1nj=1md2[gcd(i,j)=d]=d=1nd2i=1dnj=1dm[gcd(i,j)=1]=d=1nd2k=1dnμ(k)dkndkm=T=1nTnTmkTμ(k)(kT)2=T=1nTnTm(μId2)(T)
整除分块即可。

考虑对积性函数 g = μ ∗ Id ⁡ 2 g = \mu * \operatorname{Id}_2 g=μId2 进行线性筛:

  • i ∈ P i\in \mathbb{P} iP g ( i ) = p 2 − 1 g(i) = p^2 - 1 g(i)=p21
  • p j ∤ i p_j\nmid i pji g ( i ⋅ p j ) = g ( i ) ⋅ g ( p j ) g(i\cdot p_j) = g(i) \cdot g(p_j) g(ipj)=g(i)g(pj)
  • p j ∣ i p_j\mid i pji:显然只有原来对 i i i 有贡献的 μ ( k ) \mu(k) μ(k) 现在还会有贡献,唯一不同的是后面的 ( T k ) 2 \left(\dfrac{T}{k}\right)^2 (kT)2 多乘了个 p j 2 p_j^2 pj2,即 g ( i ⋅ p j ) = g ( i ) ⋅ p j 2 g(i\cdot p_j) = g(i) \cdot p_j^2 g(ipj)=g(i)pj2

时间复杂度为 O ( n + T n ) \Omicron(n + T\sqrt{n}) O(n+Tn )

Code

// 18 = 9 + 9 = 18.
#include <iostream>
#include <cstdio>
#define Debug(x) cout << #x << "=" << x << endl
typedef long long ll;
using namespace std;

const int MAXN = 2e7 + 5;
const int N = 2e7;
const int MOD = 1e9 + 7;
typedef int arr[MAXN];

int add(int a, int b) {return (a + b) % MOD;}
int sub(int a, int b) {return (a - b + MOD) % MOD;}
int mul(int a, int b) {return (ll)a * b % MOD;}

arr p, g, sum;
bool vis[MAXN];

void pre()
{
	g[1] = sum[1] = 1;
	for (int i = 2; i <= N; i++)
	{
		if (!vis[i])
		{
			p[++p[0]] = i;
			g[i] = mul(i, i) - 1;
		}
		sum[i] = add(sum[i - 1], g[i]);
		for (int j = 1; j <= p[0] && i * p[j] <= N; j++)
		{
			vis[i * p[j]] = true;
			if (i % p[j] == 0)
			{
				g[i * p[j]] = mul(g[i], mul(p[j], p[j]));
				break;
			}
			g[i * p[j]] = mul(g[i], g[p[j]]);
		}
	}
}

int GetSum(int l, int r)
{
	return sub(sum[r], sum[l - 1]);
}

int f(int n, int m)
{
	if (n > m)
	{
		swap(n, m);
	}
	int res = 0;
	for (int l = 1, r; l <= n; l = r + 1)
	{
		int k1 = n / l, k2 = m / l;
		r = min(n / k1, m / k2);
		res = add(res, mul(mul(k1, k2), GetSum(l, r)));
	}
	return res;
}

int main()
{
	pre();
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int n, m, p;
		scanf("%d%d%d", &n, &m, &p);
		printf("%d\n", add(add(mul(p, f(n, m)), mul(m, f(n, p))), mul(n, f(m, p)))); 
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值