hdu 1299 Diophantus of Alexandria (素数筛选)

本文介绍了一种用于求解特定数学问题的算法,该问题是在给定n的情况下求满足1/x+1/y=1/n的所有正整数对(x,y)的数量。文章详细解释了解决方案背后的数学原理,并提供了一段C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意就是给定 n的情况下  求满足1/x+1/y=1/n的x y 的组合数

x y 的值为正 所以x y 的值一定大于n 

不妨设 y=n+k  则 x=n*n/k+k  此时就是求n*n整除k的组合数了。。。

就是一个整除问题咯 就是求n*n的因字数

由于任何一个正整数都可以表示成 素数的x次方之积   

即 n=p1^e1*p2^e2……px^ex  

所以  ans=(1+2*e1)*(1+2*e2)*……*(1+ex)

下面是个人的一些猜测:

当n为一个很大的数(不超过数据范围)时  40000以内的素数已经足够用来表示 如果n为一个很大的素数时 40000以内的素数无法进行分解  所以最后的ans要乘以3 当然 n可以分解为40000以内的素数和40000意外的素数之积时也要ans*=3


在这里呢。。还要说下网上的那个huicpc39的素数筛选法 是博士原创的。。很厉害啊有木有。。。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>

#define eps 1e-8
#define op operator
#define MOD  10009
#define MAXN  40000
#define INF 0x7fffffff

#define FOR(i,a,b)  for(int i=a;i<=b;i++)
#define FOV(i,a,b)  for(int i=a;i>=b;i--)
#define REP(i,a,b)  for(int i=a;i<b;i++)
#define REV(i,a,b)  for(int i=a-1;i>=b;i--)
#define MEM(a,x)    memset(a,x,sizeof a)
#define ll __int64

using namespace std;

int pri[30000];
bool isprime[MAXN>>1];
int num;

void init()//素数筛选
{
    MEM(isprime,1);
    int sq=(int)sqrt(MAXN*1.0);
    pri[0]=2;
    for(int i=3;i<MAXN;i+=2)
    {
        if(isprime[(i-3)>>1])
        {
            if(i<=sq+3)
            {
                for(int j=i*i;j<MAXN;j+=2*i)
                {
                    isprime[(j-3)>>1]=0;
                }
            }
            pri[++num]=i;
        }
    }
//    for(int i=0;i<=100;i++)
//        cout<<pri[i]<<"\t";
}

int main()
{
//freopen("ceshi.txt","r",stdin);
    num=0;
    init();
//    cout<<num<<endl;
    int tc;
    scanf("%d",&tc);
    int cs=1;

    while(tc--)
    {
        int n;
        scanf("%d",&n);
        int ans=1;
//        int sq=sqrt(n*1.0);
        for(int i=0;i<=num&&n>1;i++)
        {
//            int tmp=n;
            int cnt=0;
//            cout<<"iiii  "<<i<<"   "<<pri[i]<<endl;
            while(n%pri[i]==0&&n>1)
            {
               n/=pri[i];
                cnt++;
            }
            ans*=(1+2*cnt);
        }
        if(n>1) ans*=3;
        printf("Scenario #%d:\n",cs++);
        printf("%d\n\n",(ans+1)/2);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值