ProjectEuler 108 Diophantine reciprocals I

1x+1y=1n
=> 1y=xnnx
=> y=nxxn

b=xn,x=b+n
y=nxxn
=> y=n(b+n)b=n+n2b

所以当 b|n2 时,存在一组答案。
又因为 b=xn , gcd(nx,xn)=xn=b ,且 nxn(xn)=n2 ,说明 nxxn 的一个线性组合能够组成 n2 ,说明 b|n2 总是成立。

因为是求不同的组合数,特别的,当 x==y 时,只计数一次。
d(x)x ,所以答案为 d(n2)+12

我写的暴力..直接用的大数分解

#include <bits/stdc++.h>
using namespace std;
#define all(x) x.begin(), x.end()
typedef long long LL;
#define case 3

LL Get_rand(LL n){
    return 2 + rand()%(n-2);
}

LL Mul(LL a,LL b,LL m){
    LL ans = 0;
    while(b){
        if(b & 1){
            ans = (ans + a) % m;
            b--;
        }
        else{
            a = (2 * a) % m;
            b >>= 1;
        }
    }
    return ans%m;
}

LL Quick_mod(LL a,LL n,LL m){
    LL ans = 1;
    while(n){
        if(n & 1){
            ans = Mul(ans, a, m);
        }
        a = Mul(a, a, m);
        n >>= 1;
    }
    return ans;
}

bool Miller_Rabbin(LL n){
    if (n==2)return true;
    if (n<2||!(n&1))return false;
    int t=0;
    LL a,x,y,u=n-1;
    while((u&1)==0) t++,u>>=1;
    for(int i=0;i<case;i++){
        a=rand()%(n-1)+1;
        x=Quick_mod(a,u,n);
        for(int j=0;j<t;j++){
            y=Mul(x,x,n);
            if (y==1&&x!=1&&x!=n-1)
                return false;
            ///其中用到定理,如果对模n存在1的非平凡平方根,则n是合数。
            ///如果一个数x满足方程x^2≡1 (mod n),但x不等于对模n来说1的两个‘平凡’平方根:1或-1,则x是对模n来说1的非平凡平方根
            x=y;
        }
        if (x!=1)///根据费马小定理,若n是素数,有a^(n-1)≡1(mod n).因此n不可能是素数
            return false;
    }
    return true;
}

long long factor[1000];//质因数分解结果(刚返回时是无序的)
int tol;//质因数的个数。数组小标从0开始

long long gcd(long long a,long long b){
    if(a==0)return 1;
    if(a<0) return gcd(-a,b);
    while(b)
    {
        long long t=a%b;
        a=b;
        b=t;
    }
    return a;
}

long long Pollard_rho(long long x,long long c){
    long long i=1,k=2;
    long long x0=rand()%x;
    long long y=x0;
    while(1){
        i++;
        x0=(Mul(x0,x0,x)+c)%x;
        long long d=gcd(y-x0,x);
        if(d!=1&&d!=x) return d;
        if(y==x0) return x;
        if(i==k){y=x0;k+=k;}
    }
}
//对n进行素因子分解

map<LL, int> mp;
void findfac(long long n){
    if(Miller_Rabbin(n))//素数
    {
        mp[n]++;
        return;
    }
    long long p=n;
    while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);
    findfac(p);
    findfac(n/p);
}

LL get() {
    LL res = 1;
    for(auto it:mp) {
        res *= (it.second + 1);
    }
    return res;
}

int main() {
    int i;

    for(i= 2; ; i++) {
        mp.clear();
        findfac(1LL*i*i);
//        cout<<i<<" "<<get()<<endl;
        if((get()+1)/2 >= 1000) break;
    }
    cout<<i;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/meopass/article/details/79824037
108