[SDOI2015]约数个数和

iv.[SDOI2015]约数个数和

完蛋了,我们前几题里面都有gcd(),但是这道题没有,怎么办呢?

引理:

d(ij)=x|iy|j[gcd(x,y)==1]

换句话说,两个数(i,j)积的因数个数,等于i的所有因数与j的所有因数中互质的对数。

简单证明(感谢suncongbo巨佬的讲解):

显然各质因数之间相互独立(最后是个数乘在一起,只要每一项都相等,乘积也就相等),我们不如只考虑一个质因数p。设它在i中的次数是a,在j中的次数是b。那么,在乘积ij中,次数就是a+b

考虑仅p一项为ij贡献了多少因数。显然,是a+b+1个,次数从0一直到i+j

那么为等式右侧贡献了多少呢?当i中不取任何p时,j中可以取1bp,共b种;当j中不取任何p时,i中可以取1ap,共a种;除此之外,还有一种ij都不选的,共1种。综上,为等式右侧它也贡献了a+b+1

因为对于每一个单独的p,等式左右的贡献相等;所以综合起来考虑,等式左右贡献的积也相等。

证毕。

然后我们看一看套上这个东西后我们要求什么:

ans=i=1nj=1mx|iy|j[gcd(x,y)==1]

这个时候,我们就应该想想有没有可能调换枚举顺序。

优先枚举xy,则对于每个x,有nx个这样的i,满足in并且x|i。对于每个y,则有my个这样的j

因此有ans=i=1nj=1mnimj[gcd(i,j)==1]

老套路,设f(x)=i=1nj=1mnimj[gcd(i,j)==x]g(x)=x|df(d)

反演一下,得f(x)=x|dg(d)μ(dn)

我们要求的是f(1)f(1)=x|1g(d)μ(d1)=x=1g(d)μ(d)

我们看一下g(d)是什么。

g(x)=x|df(d)=x|di=1nj=1mnimj[gcd(i,j)==d]

发现这个d可以是任何x的倍数。因此有g(x)=i=1nj=1mnimj[x|gcd(i,j)]

我们将x除出来,有

g(x)=i=1nxj=1mxnixmjx[1|gcd(i,j)]=i=1nxj=1mxnixmjx

我们令一个sum(x)=i=1xxi,这个东西可以在O(nn)时间内通过整除分块写出来。

g(x)=sum(nx)sum(mx)

又有ans=x=1g(d)μ(d),这东西也可以整除分块,因为里面有一个可以整除分块的g(d)和一个可以求前缀和的μ(d)

然后就可以了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int T,n,m,mu[50100],pri[50100],sum[50100],res;
void getmu(int N){
	mu[1]=1;
	for(int i=2;i<=N;i++){
		if(!pri[i])pri[++pri[0]]=i,mu[i]=-1;
		for(int j=1;j<=pri[0]&&i*pri[j]<=N;j++){
			pri[i*pri[j]]=true;
			if(!(i%pri[j]))break;
			mu[i*pri[j]]=-mu[i];
		}
	}
	for(int i=1;i<=N;i++)mu[i]+=mu[i-1];
}
void getsum(int N){
	for(int i=1;i<=N;i++)for(int l=1,r;l<=i;l=r+1)r=i/(i/l),sum[i]+=(r-l+1)*(i/l);
}
signed main(){
	scanf("%lld",&T),getmu(50000),getsum(50000);
	while(T--){
		scanf("%lld%lld",&n,&m);
		if(n>m)swap(n,m);
		res=0;
		for(int l=1,r;l<=n;l=r+1)r=min(n/(n/l),m/(m/l)),res+=(mu[r]-mu[l-1])*sum[n/l]*sum[m/l];
		printf("%lld\n",res);
	}
	return 0;
}

posted @   Troverld  阅读(45)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示