51nod1223 分数等式的数量
Time Limit:6 秒 Memory Limit:128GB
Description
有这样一个分数等式:
1X+1Y=1N
,(X,Y,N > 0)。给出L,求有多少满足X < Y <= L的等式。
例如:L = 12,满足条件的等式有3个,分别是:
13+16=12,14+112=13,16+112=14
。
Input
输入1个数L(1 <= L <= 10^11)
Output
输出符合条件的等式的数量。
Sample Input
12
Sample Output
3
解题思路
∵1x+1y=x+yxy∴如果1x+1y=1n,那么x+y|xy
令
d=gcd(x,y),x=dx′,y=dy′
,则
dx′+dy′|x′y′d2→x′+y′|x′y′d
∵gcd(x′,y′)=1∴x′+y′|d
因此
Ans=∑X=1L∑Y=X+1L[X+Y|XY]=∑x′=1L∑y′=x′+1L[gcd(x′,y′)=1]∑x′+y′|d,y′d<=L1=∑x′=1L∑y′=x′+1L⌊Ly′x′+y′⌋[gcd(x′,y′)=1]=∑x=1L∑y=x+1L⌊Lyx+y⌋∑k|gcd(x,y)μ(k)=∑k=1Lμ(k)∑y=1Lk∑x=1y−1⌊Lkykx+ky⌋=∑k=1L√μ(k)∑y=1L√k∑T=y+12Y−1⌊Lk2yT⌋(用T代替x+y,k2>L则⌊Lk2yT⌋=0,(x+y)y>y2>Lk2−−−√同样值为0)
最后一个下取整求和分块处理好了。
时间复杂度?
O(∑k=1L√∑y=1L√kLk2y−−−−√)=O(∑k=1L√1k∑y=1L√kLy−−√)=O(∑k=1L√1k∑x=1L√k√L−−√x((x+1)2−x2))=O(∑k=1L√1k∑x=1L√k√L−−√)=O(∑k=1L√(L−−√k)32)<O(∑k=1L√L34k)=O(L34logL−−√)
交上去很小很小就是了。
#include<cstring>
#include<cstdio>
#include<cctype>
#include<algorithm>
#define N 1001001
using namespace std;
typedef long long ll;
ll L,mu[N],pr[N];
bool bz[N];
ll sum(ll n,ll h,ll t){
ll ans=0;
for(ll i=h,j;i<=n && i<=t;i=j+1){
j=min(t,n/(n/i));ans=ans+(n/i)*(j-i+1);
}return ans;
}
int main(){
scanf("%lld",&L);
mu[1]=1;
for(ll i=2;i<N;i++){
if(!bz[i])mu[pr[++pr[0]]=i]=-1;
for(int j=1;j<=pr[0] && i*pr[j]<N;j++){
bz[i*pr[j]]=1;mu[i*pr[j]]=-mu[i];
if(i%pr[j]==0){mu[i*pr[j]]=0;break;}
}
}
ll ans=0;
for(ll k=1;k*k<=L;k++)if(mu[k])
for(ll Y=1;Y*Y*k*k<=L;Y++)ans=ans+mu[k]*sum(L/Y/k/k,Y+1,Y+Y-1);
printf("%lld",ans);
}