【NOIP2017提高组模拟12.10】神炎皇

Description

神炎皇乌利亚很喜欢数对,他想找到神奇的数对。
对于一个整数对(a,b),若满足a+b<=n且a+b是ab的因子,则成为神奇的数对。请问这样的数对共有多少呢?

Solution

要求ab是a+b的倍数,那么我们先设 d=gcd(a,b)
a=adb=bd
所以 d(a+b)|d2ab=>a+b|dab
所以d是a’b’的倍数

证明:
因为a’与b’互质,所以(a’+b’)与a’b’
因为{gcd(a’,b’)=1}=>{gcd(a’+b’,b’)=1}
所以(a’+b’)与a’互质,同理(a’+b’)与b’互质,所以(a’+b’)与a’b’互质

现在要求d(a’+b’)<=n,所以设d=(a’+b’)k。
移一下项 (a+b)2k<=n>k<=n(a+b)2

然后枚举(a’+b’),范围 1...n ,然后在(a’+b’)中与(a’+b’)互质的数一共有 φ(a+b) 个,所以a’与b’互质的个数一共有 φ(a+b) 对。

所以 ans=ni=1φ(i)ni2

Code

#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=500007;
ll i,j,k,l,t,n,m,ans;
int phi[maxn*20],p[maxn*20];
bool bz[maxn*20];
int main(){
    freopen("uria.in","r",stdin);
    freopen("uria.out","w",stdout);
    scanf("%lld",&n);
    fo(i,2,10000000){
        if(!bz[i]){
            p[++p[0]]=i;
            phi[i]=i-1;
        }
        fo(j,1,p[0]){
            t=p[j]*i;
            if(t>10000000)break;
            bz[t]=1;
            if(i%p[j]==0){
                phi[t]=phi[i]*p[j];
                break;
            }
            phi[t]=phi[i]*(p[j]-1);
        }
    }
    fo(i,1,sqrt(n)){
        ans+=phi[i]*(n/(i*i));
    }
    printf("%lld\n",ans);
}

你可能感兴趣的:(noip,数论)