zoukankan      html  css  js  c++  java
  • POJ 2917 Diophantus of Alexandria ★(数论)

    题目链接http://poj.org/problem?id=2917 题目大意:给定n,求有多少种1/x + 1/y = 1/n成立(x,y为正整数) 思路:一道很经典的数论题. 我们不妨设x>=y,则x=n+1,n+2,……,n+n. 而y = 1 / (1/n - 1/x) = nx / (x - n). 令k = x - n, 则 1 <= k <= n.则y = n(n+k) / k. 因为n*k = 0(mod k), 所以答案,即y的个数就等于n*n的小于等于n的约数个数. 容易想到n*n的约数中除了n外,大于n的和小于n的是一一对应的,所以设n*n的约数为res,则ans = (res + 1) / 2. 但是因为n*n很大,所以直接求n*n的约数的不切实际的,不过我们是可以通过n的约数个数求n*n的约数个数 ------ n和n*n的素因子是一样的 我们假设n = p1^a1 * p2^a2 * …… * pi^ai,可知n的约数个数 = (a1+1)(a2+2)……(ai+1). 那么n*n = p1^(2*a1) * p2^(2*a2) * …… * pi^(2*ai),即n*n的约数个数 = (2*a1+1)(2*a2+2)……(2*ai+1).  
    #include 
    #include 
    using namespace std;
    vector  > prime;
    int solve(int n){
        for (int i = 2; i * i <= n; i ++){
            int num = 0;
            while(n % i == 0){
                num ++;
                n /= i;
            }
            prime.push_back(make_pair(i, num));
            if (n == 1)
                break;
        }
        if (n > 1){
            prime.push_back(make_pair(n, 1));
        }
        long long ans = 1;
        for (int i = 0; i < prime.size(); i ++){
            ans *= (2 * prime[i].second + 1);
        }
        return (ans + 1)/2;
    }
    int main(){
        int t, caseo = 1;
        scanf("%d",&t);
        while(t --){
            int n;
            prime.clear();
            scanf("%d",&n);
            printf("Scenario #%d:\n", caseo ++);
            printf("%d\n\n", solve(n));
        }
        return 0;
    }
    
     
    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    Java第九次作业
    Java第八次作业
    Java第七次作业
    Java第六次作业
    Java第五次作业
    Java第四次作业
    Java第三次作业
    Java第二次作业
    Java第一次作业
    高级工程师和初级工程师之间的一道坎
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4114190.html
Copyright © 2011-2022 走看看