Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.math.BigInteger;
- import java.util.ArrayList;
- public class Binomial {
- //PRIME SIEVE FOR DECOMPOSITION
- static boolean[] bs;
- static ArrayList<Integer> all_primes;
- static long size;
- public static void sieve(long upperbound){
- size = upperbound + 1; // we add 1 to include upperbound
- bs = new boolean[(int) size];
- all_primes = new ArrayList<>();
- for(long i = 2 ; i < size ; i++){
- if(!bs[(int)i]){
- for(long j = i*i ; j < size ; j+=i){
- bs[(int)j] = true;
- }
- all_primes.add((int)i);
- }
- }
- }
- //PRIME SIEVE CODE ENDS
- //Implementation with prime factor decomposition. VERY FAST for big values of N.
- //(Source: Computing Binomial Coefficients, P. Goetgheluck)
- //Requires a list of all primes less than or equal to N (generated once by the sieve)
- //REMEMBER TO CALL SIEVE FUNCTION BEFORE CALLING COMBINATION, ALSO MAKE SURE ALL PRIMES LESS THAN OR EQUAL TO N ARE GENERATED
- public static BigInteger combination(int N, int K){
- if ((K == 0) || (K == N)) return BigInteger.ONE;
- K = Math.min(N-K, K);
- int nk = N - K;
- int rootN = (int) Math.sqrt(N);
- int n_half = N/2;
- ArrayList<Integer> exponents = new ArrayList<>(); //list of the exponents of the prime factorization.
- //example: exponents = {2, 0, 1} means that the answer is 2^2 * 3^0 * 5^1
- for(int prime : all_primes){
- if(prime > N) break;
- if (prime > nk) exponents.add(1);
- else if (prime > n_half) exponents.add(0);
- else if (prime > rootN){
- if (N % prime < K % prime) exponents.add(1);
- else exponents.add(0);
- }
- else{
- int r = 0, tmpN = N, tmpK = K, a, b, total = 0;
- while(tmpN > 0){
- a = tmpN % prime;
- b = (tmpK%prime) + r;
- tmpN /= prime;
- tmpK /= prime;
- if(a<b){
- total++;
- r = 1;
- }
- else r = 0;
- }
- exponents.add(total);
- }
- }
- //joining all prime factors in one BigInteger
- BigInteger R = BigInteger.ONE;
- for(int i = 0, len = exponents.size(); i<len; i++){
- int exp = exponents.get(i);
- if(exp > 0) R = R.multiply(BigInteger.valueOf((long) Math.pow(all_primes.get(i), exp)));
- }
- return R;
- }
- public static void main(String[] args) {
- int N = 3;
- sieve(N);
- System.out.println(combination(N, 2));
- }
- }
Add Comment
Please, Sign In to add comment