P2257 YY的GCD

我的 Luogu 博客

题意描述:

i=1nj=1m[gcd(i,j)prime], T104,n,m107

solution:

反演进阶题。

先枚举一下 p 可得:

pprimei=1nj=1m[gcd(i,j)==p]

dnμ(d)={1n=10other

可得:

pprimei=1nj=1mdi,djμ(d)

先枚举一下 d 可得:

pprimed=1ndμ(d)i=1ndj=1md[gcd(i,j)==1]

=pprimed=1ndμ(d)ndpmdp

dpQ 可得:

Q=1nnQmQpQ,pprimeμ(Qp)

然后我们就可以直接把 F(Q)=pQ,pprimeμ(Qp),给求出来。

考虑枚举每个质因数 p ,那么 p 只会对他的倍数有贡献。这样的复杂度就降为 O(nlnn) 的了。

剩下的部分整除分块即可。

总的时间复杂度为 O(T(n)+nlnn) (大力吸氧就过了)

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
const int N = 1e7+10;
int T,n,m,tot;
int prime[N],mu[N],ans[N];
bool check[N];
inline int read()
{
	int s = 0,w = 1; char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
	return s * w;
}
void YYCH()
{
	mu[1] = 1;
	for(int i = 2; i <= N-5; i++)
	{
		if(!check[i])
		{
			prime[++tot] = i;
			mu[i] = -1;
		}
		for(int j = 1; j <= tot && i * prime[j] <= N-5; j++)
		{
			check[i * prime[j]] = 1;
			if(i % prime[j] == 0)
			{
				mu[i * prime[j]] = 0;
				break;
			}
			else mu[i * prime[j]] = -mu[i];
		}
	}
	for(int i = 1; i <= tot; i++)
	{
		for(int j = 1; j * prime[i] <= N-5; j++)
		{
			ans[j * prime[i]] += mu[j];
		}
	}
	for(int i = 1; i <= N-5; i++) ans[i] = ans[i-1] + ans[i];
}
int calc(int n,int m)
{
	int res = 0;
	if(n > m) swap(n,m);
	for(int l = 1, r; l <= n && l <= m; l = r+1)
	{
		r = min(n/(n/l),m/(m/l));
		res += (ans[r] - ans[l-1]) * (n/l) * (m/l);
	}
	return res;
}
signed main()
{
	T = read(); YYCH();
	while(T--)
	{
		n = read(); m = read();
		printf("%lld\n",calc(n,m));
	}
	return 0;
}

其实这道题还可以做到 O(T(n)+n) 的。

最后一步 dpQ 的时候,可以变为: Q=1nnQmQdQμ(d)isp(Qd)

后面那个 F(Q)=dQμ(d)isp(Qd) 是可以线性筛的。

i=p1p2p3...., 只有当 Qd=p1,p2,p3... 时,isp(Qd) 才成立。

1.当 Q 为质数的时候,显然 F(Q)=1

2.当 Q=1 时,显然 F(Q)=0

3.当 i % prime[j]==0 的时候: F(iprime[j])=μ(i)

证明:

此时 prime[j]i 的最小质因子 p1

F(i)=μ(ip1)+μ(ip2)+....μ(ipn)

F(ip1)=μ(ip1p1)+μ(ip1p2)+....μ(ip1pn)

显然 ip1 分解质因数后, p1 的次数是大于等于 2 的,所以除了 μ(ip1p1) 之外,其他都为零。

因为 p1 的次数大于等于 2,μ(ip1pn)=0

所以 F(ip1)=μ(i).

4.当 i % prime[j]!=0 时: F(iprime[j])=mu[i]F(i)

证明:

此时 prime[j]i 的最小质因子 p0

F(i)=μ(ip1)+μ(ip2)+....μ(ipn)

F(ip0)=μ(ip0p0)+μ(ip0p1)+μ(ip0p2)+....μ(ip0pn)

显然有 μ(ip0p1)=μ(ip1) 。假设 ip1=x ,他分解后质因数为 x=p1p2...pn

ip0p1ip1 多了个质因子 p0, 所以 μ(ip0p1)=μ(ip1)

综上:

F(ip0)=μ(ip0p0)+μ(ip0p1)+μ(ip0p2)+....μ(ip0pn)

=μ(i)μ(ip1)μ(ip2).....μ(ipn)

=μ(i)F(i)

然后就可以直接线性筛了。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
const int N = 1e7+10;
int T,n,m,tot;
int prime[N],mu[N],ans[N];
bool check[N];
inline int read()
{
	int s = 0,w = 1; char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
	return s * w;
}
void YYCH()
{
	mu[1] = 1; ans[1] = 0;
	for(int i = 2; i <= N-5; i++)
	{
		if(!check[i])
		{
			prime[++tot] = i;
			mu[i] = -1;
                        ans[i] = 1;
		}
		for(int j = 1; j <= tot && i * prime[j] <= N-5; j++)
		{
			check[i * prime[j]] = 1;
			if(i % prime[j] == 0)
			{
				mu[i * prime[j]] = 0;
                                ans[i * prime[j]] = mu[i];
				break;
			}
			else 
                        {
                                mu[i * prime[j]] = -mu[i];
                                ans[i * prime[j]] = mu[i] - ans[i];
                        }
		}
	}
	for(int i = 1; i <= N-5; i++) ans[i] = ans[i-1] + ans[i];
}
int calc(int n,int m)
{
	int res = 0;
	if(n > m) swap(n,m);
	for(int l = 1, r; l <= n && l <= m; l = r+1)
	{
		r = min(n/(n/l),m/(m/l));
		res += (ans[r] - ans[l-1]) * (n/l) * (m/l);
	}
	return res;
}
signed main()
{
	T = read(); YYCH();
	while(T--)
	{
		n = read(); m = read();
		printf("%lld\n",calc(n,m));
	}
	return 0;
}
posted @   genshy  阅读(117)  评论(1编辑  收藏  举报
编辑推荐:
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
点击右上角即可分享
微信分享提示