代码改变世界

SPOJ KPEQU Equation

2013-05-21 09:26  bootstar  阅读(303)  评论(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();
	}
}