SPOJ KPEQU Equation
2013-05-21 09:26 bootstar 阅读(301) 评论(0) 编辑 收藏 举报题目意思求解满足方程 1/N! = 1/x + 1/y 的(x, y)整数解的个数。
1/N! = 1/x + 1/y可以化为N! = x*y /(x+y),进一步转化为y = N!*x/(x - N!),令t = x - N!,那么有y = N! * (t + N!) / t,所以上述方程也就是等价于当t取整数的时候,y为整数的解的个数,换句话说(N! * (t + N!))%t == 0 也即,(N!)^2 % t = 0。对于求解方程(N!)^2%t=0也就是说t是(N!)^2的约数。所以就直接求解N!*N!的约数的个数,将N!表示成N! = p1^a1 *p2^a2...pm^am的形式,这个可以由勒让德定理快速求解,然后答案就是(2*a1+1)*(2*a2+1)...*(a*am+1)。由于数字比较大,需要用高精度来写,这里就直接用java来写了。
import java.util.*; import java.math.*; public class Main{ Scanner cin = new Scanner(System.in); int prim[] = new int[10005]; int cnt = 0; public void init(int n){ for(int i = 2; i <= n; i ++) prim[i] = 0; for(int i = 2; i <= n; i ++){ if(prim[i] == 0){ prim[cnt++] = i; for(int j = i+i; j <= n; j += i){ prim[j] = 1; } } } } int Factor(int n, int p){ int ret = 0; while(n!=0){ ret = ret + n/p; n = n/p; } return ret; } BigInteger calc(int n){ BigInteger ret = new BigInteger("1"); for(int i = 0; i < cnt && prim[i] <= n; i ++){ int t = Factor(n, prim[i]); ret = ret.multiply(BigInteger.valueOf(t*2+1)); } return ret; } public void run(){ init(10000); while(cin.hasNext()){ int n = cin.nextInt(); if(n==0) break; System.out.println(calc(n)); } } public static void main(String[] args){ Main a = new Main(); a.run(); } }