题目描述,
给定等式1/x+1/y=1/(N!),求当x>0且y>0的时候,使等式成立的解(x,y)的个数mod1000007。其中1<=N<=10^6。
题目分类:Math
题目来源:Interview Street
解:
首先明确一点,(2,1)和(1,2)诸如此类的算是不同的解。其次明确无论是具体解的个数还是X、Y以及N!均无法在计算机中表示(太大了),因此结合题目的分类,基本上是要从数学的角度来找突破点。
先把1/x+1/y=1/(N!)化简成y=f(x)的形式。
为了方便,设1/(N!)=k。所以化简可得y=x/(kx-1)。还不够直观,再化简得:y=1/k+1/(k^2)*(1/(x-1/k))。所以题目变成求函数y=1/k+1/(k^2)*(1/(x-1/k))在第一象限的且x,y都是整数的点的个数。
分析此函数可以看出,这个函数是将函数y=1/(k^2*x)在直角坐标系上向右和向上平移了1/k距离,而由原函数图像可知(单调递减、过0点、在x=1/k处达到无穷,很容易画出),原函数x,y在第一象限且均为整数的点和函数y=1/(k^2*x)在第一象限且x,y均为整数的点的数量相同,又因为1/k=N!为整数,所以问题转化成求函数y=1/(k^2*x)在第一象限的点的个数,即求使xy=1/K^2=N!*N!成立且x,y均为正整数的解的个数。
根据一些数论知识我们可以知道,任何一个整数都能表示成(a1^x1)*(a2^x2)*(a3^x3)*.......的形式,其中均是自然数,a是素数。
所以我们尝试将N!*N!表示成这种形式。
首先用素数筛筛出小于N的所有素数(O(n)复杂度,或许还要多点),然后对于所有小于N的自然数,使用求出的素数表去约,直到约成1位置,就可把N!表示成都表示成(a1^x1)*(a2^x2)*(a3^x3)*.......的形式,时间复杂度约为(O(n*sqrt(n)),博主不是很确定)。
然后即可知道N!*N!的形式是(a1^(2*x1))*(a2^(2*x2))*(a3^(2*x3))*.......,也就是个平方关系然后再带进去化简。
显然,对于一个x有唯一的y使x*y=N!*N!,因此只需要确定x的数量即可(不用担心会重复,因为(1,2)(2,1)算不同的解。
所以根据排列组合的乘法原理,x的表示方法有(2*x1+1)*(2*x2+1)*(2*x3+1)。。。。种,道理即是为了确定x,我们可以选取[0,x1]个a1,再选取[0,x2]个a2,以此类推
(+1是因为考虑可以选0)。
至此,题目已经完成,输出结果即可。
附上java代码一段仅供参考(博主很懒没有用筛,所以15个用例有一个超时了,改成筛应该就没问题了):
import java.io.*; import java.util.ArrayList; public class Solution{ public static void main(String[] argvs) { BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); try { int N=Integer.valueOf(br.readLine()); ArrayList<Integer> prime=new ArrayList<Integer>(); if(N==1) { System.out.println(1); return; } for(int i=2;i<=N;i++) { if(isPrime(i)==true) prime.add(i); } int[] k=new int[prime.size()]; for(int i=2;i<=N;i++) { int t=i; for(int j=0;j<=prime.size()-1;j++) { if(t%prime.get(j)==0) { t/=prime.get(j); k[j]++; j=-1; } if(t==1) break; } } long result=1; for(int i=0;i<=k.length-1;i++) { result*=(2*k[i]+1); result%=1000007; } System.out.println(result); } catch (NumberFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static boolean isPrime(int n) { for(int i=2;i<=Math.sqrt(n);i++) { if(n%i==0) return false; } return true; } }