题意就是给定 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;
}