[51nod 1223]分数等式的数量

27 篇文章 0 订阅
24 篇文章 0 订阅

题目大意

有这样一个分数等式:1/X + 1/Y = 1/N,(X,Y,N > 0)。给出L,求有多少满足X < Y <= L的等式。
例如:L = 12,满足条件的等式有3个,分别是:1/3 + 1/6 = 1/2, 1/4 + 1/12 = 1/3, 1/6 + 1/12 = 1/4。

数论题

大师张俊不教我我不会。。
其实就是求多少对(a,b)满足a+b|ab
设d=(a,b),a1*d=a,b1*d=b
d(a1+b1)|d2a1b1
a1+b1|da1b1
因为(a1,b1)=1,那么我们其实只需要满足
a1+b1|d
na=1nb=a+1[(a,b)=1](n/b)/(a+b)
我们莫比乌斯反演一波
nd=1μ(d)n/da=1n/db=a+1(n/d2/b)/(a+b)
nd=1n/db=1b1a=1(n/d2/b)/(a+b)
枚举前两个最后一个分块,复杂度不会算。

#include<cstdio>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=320000+10;
int mu[maxn],pri[maxn];
bool bz[maxn];
int i,j,k,l,t,m,top,a,b,d;
ll ans,n;
void calc(int b,int d){
    int i=1,j;
    ll k;
    while (i<=b-1){
        k=(n/((ll)d*d)/(ll)b)/(ll)(i+b);
        if (!k) break;
        j=(n/((ll)d*d)/(ll)b)/k-(ll)b;
        j=min(j,b-1);
        ans+=(ll)mu[d]*(j-i+1)*((n/((ll)d*d)/(ll)b)/(ll)(i+b));
        i=j+1;
    }
}
int main(){
    mu[1]=1;
    fo(i,2,maxn-10){
        if (!bz[i]){
            pri[++top]=i;
            mu[i]=-1;
        }
        fo(j,1,top){
            if ((ll)i*pri[j]>maxn-10) break;
            bz[i*pri[j]]=1;
            if (i%pri[j]==0){
                mu[i*pri[j]]=0;
                break;
            }
            mu[i*pri[j]]=-mu[i];
        }
    }
    scanf("%lld",&n);
    m=floor(sqrt(n));
    fo(d,1,m){
        if (mu[d]==0) continue;
        fo(b,1,m/d) calc(b,d);
    }
    printf("%lld\n",ans);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值