3060 ProjectEuler 108

传送门

分析

看到这么个窒息的式子,难道不想化简吗?
1 x + 1 y = 1 n \dfrac{1}{x}+\dfrac{1}{y}=\dfrac{1}{n} x1+y1=n1
n ( x + y ) = x y n(x+y)=xy n(x+y)=xy
n x + n y = x y nx+ny=xy nx+ny=xy
x y − n x = n y xy-nx=ny xynx=ny
x ( y − n ) = n y x(y-n)=ny x(yn)=ny
x = n y y − n x=\dfrac{ny}{y-n} x=ynny
诶还是没有什么用啊。
那么不妨换元,设 a = y − n a=y-n a=yn
y = a + n y=a+n y=a+n
x = n ( a + n ) a x=\dfrac{n(a+n)}{a} x=an(a+n)
x = n + n 2 a x=n+\dfrac{n^2}{a} x=n+an2
诶,对于每个 a a a,都有对应的一对 x , y x,y x,y,那 a a a是什么啊?
诶对,是 n 2 n^2 n2的因子……什么?难道枚举 n 2 n^2 n2的因子吗???看着 1 e 9 1e9 1e9 n n n,我不禁陷入了沉思……
诶我可以枚举 n n n的因子啊,那只要到 n \sqrt{n} n 就可以了吧(大雾),于是WA得很惨烈。
咋回事?很简单,4是36的因子,但是在枚举6的因子时没有算。

所以这里写一个能算 n p n^p np的因子数的方法:分解质因数。对于一个 n n n,根据唯一分解定理,一定可以写成 p 1 i 1 ∗ p 2 i 2 ∗ p 3 i 3 . . . . . . p m i m p_1^{i_1}*p_2^{i_2}*p_3^{i_3}......p_m^{i_m} p1i1p2i2p3i3......pmim p p p为质数。
所以每个质因子都可以选 0 , 1 , 2... , i 0,1,2...,i 0,1,2...,i个,所以因子总数就是每个质因子个数的乘积。

所以只要素数筛,统计每个质因子个数为 i i i n p n^p np中就有 i ∗ p i*p ip个该因子,加上一个选 0 0 0的可能,这个因子可以选到 i ∗ p + 1 i*p+1 ip+1个。

而筛的时候只要枚举到 n \sqrt{n} n n n n除完了之后,剩下的就是大质数,再处理就可以了。

最后算出了 n 2 n^2 n2的因子数,由于 x ≤ y x\le y xy所以有序,要除以 2 2 2但是 n ∗ n n*n nn不能除2,因为只算了一遍。故最后答案是 c n t + 1 2 \dfrac{cnt+1}{2} 2cnt+1

代码

#include<bits/stdc++.h>
#define ll long long
#define inf 1<<30
using namespace std;
const int MAXN=1e5+10;
int p[MAXN];
int main()
{
	ll n,ans=1;
	scanf("%lld",&n);
	for(int i=2;i*i<=n;i++){
		if(p[i]) continue;
		for(int j=i*2;j*j<=n;j+=i) p[j]=1;
		if(n%i==0){
			ll cnt=0;
			while(n%i==0) n/=i,cnt++;
			ans=ans*(cnt*2ll+1);
		}
	}
	if(n!=1) ans*=3ll;//大质数
	printf("%lld\n",(ans+1)/2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值