SPOJ Equation :求 1/n!=1/x+1/y 的解的个数

来源:互联网 发布:前苏联挖到地狱知乎 编辑:程序博客网 时间:2024/06/06 00:05

Description

You are given integer positive number N. Find the number of solutions in positive integer numbers of the following equation:

1/N! = 1/X + 1/Y

Input

Each line of input file contains one integer number N (1 ≤ N ≤ 104). The last line contains 0 and shouldn't be processed. Number of lines in the input does not exceed 30.

Output

For every line in the input write the answer on a separate line.

Sample Input

Input:120Output:13
//题目就是求1/n! = 1/x + 1/y 的解的个数,看样例知要考虑(x,y)对数的关系。
//设 m=n! ,由等式知x,y必定大于n!,所以再设 x=n!+k=m+k 带入 1/m=1/x+1/y 中化简得到y=m*m/k+m,因y为整数,所以要求k整除m*m,即k为m*m的因子,问题便转化为求n!*n!的因子个数, 设n!=p1^e1 * p2^e2 * p3^e3 *...*pk^ek,则 n!*n!= p1^(2*e1) * p2^(2*e2) *...*pk^(2*ek) 。 则因子个数sum=(2*e1+1)*(2*e2+1)*...*(2*ek+1); 答案很大,需要高精度。用java处理方便!
 import java.util.Scanner; import java.io.*; import java.math.*; import java.math.BigInteger;   public class Main {      static boolean x[]=new boolean[10000+10];      static int prime[]=new int[10000+10],num[]=new int[10000+10],cnt=0;      public static void Init()      {          int i,tmp;          for(i=0;i<=10000;i++) x[i]=false;          x[0]=x[1]=true;          for(i=2;i<=10000;i++)               if(x[i]==false)               {                    prime[++cnt]=i;                    tmp=i*i;                    while(tmp<=10000)                    {                         x[tmp]=true;                         tmp+=i;                    }               }      }      public static void main(String[] args)      {          Scanner cin=new Scanner(System.in);          Init();          int n,i,tmp;          while(cin.hasNext())          {               n=cin.nextInt();               if(n==0) break;               for(i=0;i<=10000;i++) num[i]=0;               for(i=1;i<=cnt&&prime[i]<=n;i++) //分解出n!内所有因子的个数               {                    tmp=n;                    while(true)                    {                         if(tmp==0||(prime[i]>n))                              break;                         num[i]+=tmp/prime[i];                         tmp/=prime[i];                    }               }               BigInteger ans=BigInteger.ONE;               for(i=1;i<=cnt&&prime[i]<=n;i++)                    if(num[i]>=1)                         ans=ans.multiply(BigInteger.valueOf(2*num[i]+1));               System.out.println(ans);          }      } }