洛谷P5253 丢番图

题目大意

1 x + 1 y = 1 n \frac{1}{x}+\frac{1}{y}=\frac{1}{n} x1+y1=n1的解的个数

题目分析

其实就是化(luan)简(gao)
1 x + 1 y = 1 n \frac{1}{x}+\frac{1}{y}=\frac{1}{n} x1+y1=n1
y x y + x x y = 1 n \frac{y}{xy}+\frac{x}{xy}=\frac{1}{n} xyy+xyx=n1
两边同乘xy得
x + y = x y n x+y=\frac{xy}{n} x+y=nxy
再同乘 − n -n n
− n ( x + y ) = − x y -n(x+y)=-xy n(x+y)=xy
同时加上 n 2 n^2 n2
n 2 − n ( x + y ) = n 2 − x y n^2-n(x+y)=n^2-xy n2n(x+y)=n2xy
去括号得
n 2 − n x − n y = n 2 − x y n^2-nx-ny=n^2-xy n2nxny=n2xy
移项得
n 2 − n x − n y + x y = n 2 n^2-nx-ny+xy=n^2 n2nxny+xy=n2
根据多项式的乘法化简左边的式子得
( x − n ) ( y − n ) = n 2 (x-n)(y-n)=n^2 (xn)(yn)=n2
化(luan)简(gao)完毕
  对于每一个可能的(x-n),都必定会有一个(y-n)与其对应;而(x-n)是 n 2 n^2 n2的约数,去除重合的情况,问题转化成求 n 2 n^2 n2的约数的个数向上取整。
  思考到这里,开心的你看了看题目数据,然后发现用(sang)心(xin)良(bing)苦(kuang)的出题人把数据出到了 1 0 14 10^{14} 1014。于是,O(n)求约数个数的办法被无情地否决了。
  那我们应该怎么办呢?这时我们应该祭出一个定理——“唯一分解定理”!!!那么它是什么呢?

任 意 大 于 1 的 自 然 数 都 能 被 质 数 的 指 数 幂 的 乘 积 表 示 任意大于1的自然数都能被质数的指数幂的乘积表示 1

然并卵……
好了其实我们用到的其实是它的推论,准确地来说是

  • 若 可 以 将 n 分 解 为 p 1 c 1 ∗ p 2 c 2 ∗ … ∗ p k c k ( n > 1 ) 若可以将n分解为p1^{c1}*p2^{c2}*…*pk^{ck}(n>1) np1c1p2c2pkck(n>1)
  • 则 n 的 正 约 数 个 数 为 ( c 1 + 1 ) ∗ ( c 2 + 1 ) ∗ … ∗ ( c k + 1 ) 则n的正约数个数为(c1+1)*(c2+1)*…*(ck+1) n(c1+1)(c2+1)(ck+1)

它的原理就不在这里介绍了,我认为度娘会解释得很好的。

Code

#include<iostream>
#include<cstdio>
using namespace std;
long long ans=1,n;
int main(){
	scanf("%lld",&n);//输入n
	for(long long i=2,cnt=0;i*i<=n;i++){//唯一分解定理的推论
		if(n%i==0){
			long long cnt=0;
			while(n%i==0)n/=i,++cnt;//求c的值
			ans*=cnt*2+1;//直接乘上去
		}
	}
	if(n>1) ans*=3;//假如n没有被除完,ans*=1*2+1,这里的代码是化简后的
	ans=(ans+1)/2;//ans除以2向上取整
	printf("%lld",ans);//输出
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值