I am trying to solve some range minimum query where the minima must be above some constant.
Problem:
Given some positive integers a1, ... aN. For each query of integers l, r, d find the minimal element that is still greater than d, that is find min{a_i | l <= i <= r, a_i > d}.
I already tried the segment tree algorithm with an additional sparse table to speed up the queries when all elements are above d. This gave me an complexity of O(N * log(N) + Q * log(N)). Using the sparse table did not improve the complexity, but it pruned a lot of the calls for the segment tree query.
However, this algorithm is still too slow. Does anybody has a faster algorithm that I could try?
Edit:
People are pointing out that it has to do with my implementation and that I am using the correct data structure. So here is my code, maybe I did something wrong that increased the complexity:
#include <bits/stdc++.h>
const int32_t MAX_N = 100005;
const int32_t LOG_N = 10;
int32_t sparse_table[MAX_N][LOG_N];
std::vector<int32_t> deviations;
std::vector<int32_t> segment_tree;
void build_sparse_table(int32_t N)
{
for (int32_t i = 0; i < N; i++) {
sparse_table[i][0] = deviations[i];
}
for (int32_t k = 1; k < LOG_N; k++) {
for (int32_t i = 0; i + (1 << k) - 1 < N; i++) {
sparse_table[i][k] = std::min(sparse_table[i][k - 1], sparse_table[i + (1 << (k - 1))][k - 1]);
}
}
}
void build_segment_tree(int32_t p, int32_t l, int32_t r)
{
if (l == r) {
segment_tree[p] = deviations[l];
return;
}
int32_t m = (l + r) / 2;
build_segment_tree(2 * p, l, m);
build_segment_tree(2 * p + 1, m + 1, r);
segment_tree[p] = std::min(segment_tree[2 * p], segment_tree[2 * p + 1]);
}
int32_t query_sparse_table(int32_t l, int32_t r)
{
int32_t length = r - l + 1;
int32_t k = 31 - __builtin_clz(length);
if (l > r || k >= LOG_N) {
return -1;
}
return std::min(sparse_table[l][k], sparse_table[r - (1 << k) + 1][k]);
}
int32_t query_segment_tree(int32_t p, int32_t l, int32_t r, int32_t i, int32_t j, int32_t d)
{
int32_t maybe_result = query_sparse_table(i, j);
if (maybe_result > d) {
return maybe_result;
}
if (i > j) {
return -1;
}
if (i == l && j == r) {
if (segment_tree[p] > d) {
return segment_tree[p];
}
}
if (l == r) {
return (segment_tree[p] > d) ? segment_tree[p] : -1;
}
int32_t m = (l + r) / 2;
int32_t ql = query_segment_tree(2 * p, l, m, i, std::min(j, m), d);
int32_t qr = query_segment_tree(2 * p + 1, m + 1, r, std::max(i, m + 1), j, d);
return (ql != -1 && qr != -1) ? std::min(ql, qr) : std::max(ql, qr);
}
int32_t query_segment_tree(int32_t l, int32_t r, int32_t d)
{
return query_segment_tree(1, 0, deviations.size() - 1, l, r, d);
}
Here’s another approach, that runs in linearithmic time.
We sweep a quantity x from −∞ to ∞. Whenever x = d for some query, we
insert [ℓ, r] into an interval tree. Whenever x = ai for
some i, we delete all of the intervals that contain i, reporting i as
their result. We resolve nondeterminism by doing the latter before the
former.
The cost is sorting the array, sorting the intervals by d, merging them
into an event array, and performing an amortized logarithmic time
operation for each one.
Related
Here I try to write a program in C++ to find NCR. But I've got a problem in the result. It is not correct. Can you help me find what the mistake is in the program?
#include <iostream>
using namespace std;
int fact(int n){
if(n==0) return 1;
if (n>0) return n*fact(n-1);
};
int NCR(int n,int r){
if(n==r) return 1;
if (r==0&&n!=0) return 1;
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
};
int main(){
int n; //cout<<"Enter A Digit for n";
cin>>n;
int r;
//cout<<"Enter A Digit for r";
cin>>r;
int result=NCR(n,r);
cout<<result;
return 0;
}
Your formula is totally wrong, it's supposed to be fact(n)/fact(r)/fact(n-r), but that is in turn a very inefficient way to compute it.
See Fast computation of multi-category number of combinations and especially my comments on that question. (Oh, and please reopen that question also so I can answer it properly)
The single-split case is actually very easy to handle:
unsigned nChoosek( unsigned n, unsigned k )
{
if (k > n) return 0;
if (k * 2 > n) k = n-k;
if (k == 0) return 1;
int result = n;
for( int i = 2; i <= k; ++i ) {
result *= (n-i+1);
result /= i;
}
return result;
}
Demo: http://ideone.com/aDJXNO
If the result doesn't fit, you can calculate the sum of logarithms and get the number of combinations inexactly as a double. Or use an arbitrary-precision integer library.
I'm putting my solution to the other, closely related question here, because ideone.com has been losing code snippets lately, and the other question is still closed to new answers.
#include <utility>
#include <vector>
std::vector< std::pair<int, int> > factor_table;
void fill_sieve( int n )
{
factor_table.resize(n+1);
for( int i = 1; i <= n; ++i )
factor_table[i] = std::pair<int, int>(i, 1);
for( int j = 2, j2 = 4; j2 <= n; (j2 += j), (j2 += ++j) ) {
if (factor_table[j].second == 1) {
int i = j;
int ij = j2;
while (ij <= n) {
factor_table[ij] = std::pair<int, int>(j, i);
++i;
ij += j;
}
}
}
}
std::vector<unsigned> powers;
template<int dir>
void factor( int num )
{
while (num != 1) {
powers[factor_table[num].first] += dir;
num = factor_table[num].second;
}
}
template<unsigned N>
void calc_combinations(unsigned (&bin_sizes)[N])
{
using std::swap;
powers.resize(0);
if (N < 2) return;
unsigned& largest = bin_sizes[0];
size_t sum = largest;
for( int bin = 1; bin < N; ++bin ) {
unsigned& this_bin = bin_sizes[bin];
sum += this_bin;
if (this_bin > largest) swap(this_bin, largest);
}
fill_sieve(sum);
powers.resize(sum+1);
for( unsigned i = largest + 1; i <= sum; ++i ) factor<+1>(i);
for( unsigned bin = 1; bin < N; ++bin )
for( unsigned j = 2; j <= bin_sizes[bin]; ++j ) factor<-1>(j);
}
#include <iostream>
#include <cmath>
int main(void)
{
unsigned bin_sizes[] = { 8, 1, 18, 19, 10, 10, 7, 18, 7, 2, 16, 8, 5, 8, 2, 3, 19, 19, 12, 1, 5, 7, 16, 0, 1, 3, 13, 15, 13, 9, 11, 6, 15, 4, 14, 4, 7, 13, 16, 2, 19, 16, 10, 9, 9, 6, 10, 10, 16, 16 };
calc_combinations(bin_sizes);
char* sep = "";
for( unsigned i = 0; i < powers.size(); ++i ) {
if (powers[i]) {
std::cout << sep << i;
sep = " * ";
if (powers[i] > 1)
std::cout << "**" << powers[i];
}
}
std::cout << "\n\n";
}
The definition of N choose R is to compute the two products and divide one with the other,
(N * N-1 * N-2 * ... * N-R+1) / (1 * 2 * 3 * ... * R)
However, the multiplications may become too large really quick and overflow existing data type. The implementation trick is to reorder the multiplication and divisions as,
(N)/1 * (N-1)/2 * (N-2)/3 * ... * (N-R+1)/R
It's guaranteed that at each step the results is divisible (for n continuous numbers, one of them must be divisible by n, so is the product of these numbers).
For example, for N choose 3, at least one of the N, N-1, N-2 will be a multiple of 3, and for N choose 4, at least one of N, N-1, N-2, N-3 will be a multiple of 4.
C++ code given below.
int NCR(int n, int r)
{
if (r == 0) return 1;
/*
Extra computation saving for large R,
using property:
N choose R = N choose (N-R)
*/
if (r > n / 2) return NCR(n, n - r);
long res = 1;
for (int k = 1; k <= r; ++k)
{
res *= n - k + 1;
res /= k;
}
return res;
}
A nice way to implement n-choose-k is to base it not on factorial, but on a "rising product" function which is closely related to the factorial.
The rising_product(m, n) multiplies together m * (m + 1) * (m + 2) * ... * n, with rules for handling various corner cases, like n >= m, or n <= 1:
See here for an implementation nCk as well as nPk as a intrinsic functions in an interpreted programming language written in C:
static val rising_product(val m, val n)
{
val acc;
if (lt(n, one))
return one;
if (ge(m, n))
return one;
if (lt(m, one))
m = one;
acc = m;
m = plus(m, one);
while (le(m, n)) {
acc = mul(acc, m);
m = plus(m, one);
}
return acc;
}
val n_choose_k(val n, val k)
{
val top = rising_product(plus(minus(n, k), one), n);
val bottom = rising_product(one, k);
return trunc(top, bottom);
}
val n_perm_k(val n, val k)
{
return rising_product(plus(minus(n, k), one), n);
}
This code doesn't use operators like + and < because it is type generic (the type val represents a value of any kinds, such as various kinds of numbers including "bignum" integers) and because it is written in C (no overloading), and because it is the basis for a Lisp-like language that doesn't have infix syntax.
In spite of that, this n-choose-k implementation has a simple structure that is easy to follow.
Legend: le: less than or equal; ge: greater than or equal; trunc: truncating division; plus: addition, mul: multiplication, one: a val typed constant for the number one.
the line
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
should be
else return (n*fact(n-1))/(fact(r)*fact(n-r));
or even
else return fact(n)/(fact(r)*fact(n-r));
Use double instead of int.
UPDATE:
Your formula is also wrong. You should use fact(n)/fact(r)/fact(n-r)
this is for reference to not to get time limit exceeded while solving nCr in competitive programming,i am posting this as it will be helpful to u as you already got answer for ur question,
Getting the prime factorization of the binomial coefficient is probably the most efficient way to calculate it, especially if multiplication is expensive. This is certainly true of the related problem of calculating factorial (see Click here for example).
Here is a simple algorithm based on the Sieve of Eratosthenes that calculates the prime factorization. The idea is basically to go through the primes as you find them using the sieve, but then also to calculate how many of their multiples fall in the ranges [1, k] and [n-k+1,n]. The Sieve is essentially an O(n \log \log n) algorithm, but there is no multiplication done. The actual number of multiplications necessary once the prime factorization is found is at worst O\left(\frac{n \log \log n}{\log n}\right) and there are probably faster ways than that.
prime_factors = []
n = 20
k = 10
composite = [True] * 2 + [False] * n
for p in xrange(n + 1):
if composite[p]:
continue
q = p
m = 1
total_prime_power = 0
prime_power = [0] * (n + 1)
while True:
prime_power[q] = prime_power[m] + 1
r = q
if q <= k:
total_prime_power -= prime_power[q]
if q > n - k:
total_prime_power += prime_power[q]
m += 1
q += p
if q > n:
break
composite[q] = True
prime_factors.append([p, total_prime_power])
print prime_factors
Recursive function is used incorrectly here. fact() function should be changed into this:
int fact(int n){
if(n==0||n==1) //factorial of both 0 and 1 is 1. Base case.
{
return 1;
}else
return (n*fact(n-1));//recursive call.
};
Recursive call should be made in else part.
NCR() function should be changed into this:
int NCR(int n,int r){
if(n==r) {
return 1;
} else if (r==0&&n!=0) {
return 1;
} else if(r==1)
{
return n;
}
else
{
return fact(n)/(fact(r)*fact(n-r));
}
};
// CPP program To calculate The Value Of nCr
#include <bits/stdc++.h>
using namespace std;
int fact(int n);
int nCr(int n, int r)
{
return fact(n) / (fact(r) * fact(n - r));
}
// Returns factorial of n
int fact(int n)
{
int res = 1;
for (int i = 2; i <= n; i++)
res = res * i;
return res;
}
// Driver code
int main()
{
int n = 5, r = 3;
cout << nCr(n, r);
return 0;
}
I have a problem with the Quick Sort algorithm that I'm trying to implement.
I take a course of Fundamental Algorithms and we're provided for the laboratory assignments with pseudocode for various argorithms to implement. These algorithms are taken from Cormen and assimilated to C++ language and we're supposed to verify efficiency and generate charts for the number of assignments and comparisons within.
Now the question:
The following code is supposed to make a Quick Sort on an array of 10000 numbers and work with it in the Best Case scenario (taking the pivot of the array always at the middle):
int partition(int *a, int p, int r) {
int x = a[r];
countOpQS++;
int index = p - 1;
for (int count = p; count <= (r - 1); count++) {
if (a[count] <= x) {
index += 1;
swap(a[index], a[count]);
countOpQS += 3;
}
countOpQS++;
}
swap(a[index + 1], a[r]);
countOpQS += 3;
return (index + 1);
}
int select(int *a, int p, int r, int index) {
if (p == r) {
return a[p];
}
int q;
q = partition(a, p, r);
//countOpQS++;
int k = q - p + 1;
if (index <= k) {
return select(a, p, q - 1, index);
} else {
return select(a, q + 1, r, index - k);
}
}
void bestQuickSort(int *a, int p, int r) {
if (p < r) {
select(a, p, r, (r - p + 1) / 2);
bestQuickSort(a, p, (r - p + 1) / 2);
bestQuickSort(a, ((r - p + 1) / 2) + 1, r);
}
}
The call in the main function is done by:
for (index = 100; index <= 10000; index += 100) {
countOpQS = 0;
for (int k = 0; k < index; k++) {
a[k] = rand();
}
bestQuickSort(a, 1, index);
out3 << index << ", " << countOpQS << "\n";
}
It should be doable with these methods, but it jumps into stack overflow pretty quickly while running. I even raised the reserved stack in Visual Studio, due to it being a necessity while going into the worst case possible (already ordered array, random pivot).
Do you guys have any idea of why it doesn't work?
Firstly, you should know that your function select() rearranges the elements in the range [p, r], in such a way that the element at the index-th(note that index is one-based!) position is the element that would be in that position in a sorted sequence, just as std::nth_element does.
So when you chose the median element of the subarray by select(a, p, r, (r - p + 1) / 2);, the index of median is based on p.
For example: when p = 3, r = 5, so (r - p + 1) / 2 is 1, the median would be placed in a[4], it means you should call the function like this: select(a, 3, 5, 2). And after that, you just call the bestQuickSort() like this:
bestQuickSort(a, p, (r - p + 1) / 2); // (r - p + 1) / 2 is 1 now!
bestQuickSort(a, ((r - p + 1) / 2) + 1, r);
of course it doesn't work! The whole code for this is:
int select(int *a, int p, int r, int index) {
if (p == r) {
return a[p];
}
int q;
q = partition(a, p, r);
//countOpQS++;
int k = q - p + 1;
if(k== index)
return a[q];
else if (index <= k) {
return select(a, p, q - 1, index);
} else {
return select(a, q + 1, r, index - k);
}
}
void bestQuickSort(int *a, int p, int r) {
if (p < r) {
select(a, p, r, (r - p + 1) / 2 + 1); // the index passed to select is one-based!
int midpoint = p + (r - p + 1) / 2;
bestQuickSort(a, p, midpoint - 1);
bestQuickSort(a, midpoint + 1, r);
}
}
BTW, your version of quicksort didn't always run in best case, though every time you choose the exact median of the (sub)array, but the time complexity of select is not always O(n) since you simply choose the a[r] as the pivot, the worst-case performance of select is quadratic: O(n*n).
I found a nice math problem, but I still can't solve it, I tried to find one solution using google and found that it can be solve using the Binary Indexed Tree data structure, but the solution is not clear to me.
Here the Problem called Finding Magic Triplets, it can be found in Uva online judge:
(a + b^2) mod k = c^3 mod k, where a<=b<=c and 1 <= a, b, c <= n.
given n and k (1 <= n, k <= 10^5), how many different magic triplets exist for known values of n and k. A triplet is different from another if any of the three values is not same in both triplets.
and here the solution that I found:
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long int64;
const int MAX_K = (int)(1e5);
int N, K;
struct BinaryIndexedTree{
typedef int64 bit_t;
static const int MAX_BIT = 3*MAX_K + 1;
bit_t data[MAX_BIT+1];
int SIZE;
void init(int size){
memset(data, 0, sizeof(data));
SIZE = size;
}
bit_t sum(int n){
bit_t ret = 0;
for(;n;n-=n&-n){
ret += data[n];
}
return ret;
}
bit_t sum(int from, int to){
return sum(to)-sum(from);
}
void add(int n, bit_t x){
for(n++;n<=SIZE;n+=n&-n){
data[n]+=x;
}
}
};
BinaryIndexedTree bitree;
void init(){
scanf("%d%d", &N, &K);
}
int64 solve(){
bitree.init(2*K+1);
int64 ans = 0;
for(int64 i=N; i>=1; i--){
int64 b = i * i % K, c = i * i * i % K;
bitree.add(c, 1);
bitree.add(c+K, 1);
bitree.add(c+2*K, 1);
int64 len = i;
if(len >= K){
ans += (len / K) * bitree.sum(K);
len %= K;
}
if(len > 0){
ans += bitree.sum(b + 1, b + len + 1);
}
}
return ans;
}
int main(){
int T;
scanf("%d", &T);
for(int i=0; i<T; i++){
init();
printf("Case %d: %lld\n", i+1, solve());
}
return 0;
}
Are you determined to use BITs? I would have thought ordinary arrays would do. I would start by creating three arrays of size k, where arrayA[i] = the number of values of a in range equal to i mod k, arrayB[i] = the number of values of b in range where b^2 = i mod k, and arrayC[i] = the number of values of c in range where c^3 = i mod k. N and k are both <= 10^5 so you could just consider each value of a in turn, b in turn, and c in turn, though you can be cleverer if k is much smaller than n, because will be some sort of fiddly fence-post counting expression that allows you to work out how many numbers in the range 0..n are equal to i mod k for each i.
Given those three arrays then consider each possible pair of numbers i, j where 0<=i,j < k and work out that there are arrayA[i] * arrayB[j] pairs which have those values mod k. Sum these up in arrayAB[i + j mod k] to find the number of ways that you can chose a + b^2 mod k = x for 0<=x < k. Now you have two arrays arrayAB and arrayC, where arrayAB[i] * arrayC[i] is the number of ways of finding a triple where a + b^2 = c^3] = i, so sum this over all 0<=i < k to get your answer.
Here I try to write a program in C++ to find NCR. But I've got a problem in the result. It is not correct. Can you help me find what the mistake is in the program?
#include <iostream>
using namespace std;
int fact(int n){
if(n==0) return 1;
if (n>0) return n*fact(n-1);
};
int NCR(int n,int r){
if(n==r) return 1;
if (r==0&&n!=0) return 1;
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
};
int main(){
int n; //cout<<"Enter A Digit for n";
cin>>n;
int r;
//cout<<"Enter A Digit for r";
cin>>r;
int result=NCR(n,r);
cout<<result;
return 0;
}
Your formula is totally wrong, it's supposed to be fact(n)/fact(r)/fact(n-r), but that is in turn a very inefficient way to compute it.
See Fast computation of multi-category number of combinations and especially my comments on that question. (Oh, and please reopen that question also so I can answer it properly)
The single-split case is actually very easy to handle:
unsigned nChoosek( unsigned n, unsigned k )
{
if (k > n) return 0;
if (k * 2 > n) k = n-k;
if (k == 0) return 1;
int result = n;
for( int i = 2; i <= k; ++i ) {
result *= (n-i+1);
result /= i;
}
return result;
}
Demo: http://ideone.com/aDJXNO
If the result doesn't fit, you can calculate the sum of logarithms and get the number of combinations inexactly as a double. Or use an arbitrary-precision integer library.
I'm putting my solution to the other, closely related question here, because ideone.com has been losing code snippets lately, and the other question is still closed to new answers.
#include <utility>
#include <vector>
std::vector< std::pair<int, int> > factor_table;
void fill_sieve( int n )
{
factor_table.resize(n+1);
for( int i = 1; i <= n; ++i )
factor_table[i] = std::pair<int, int>(i, 1);
for( int j = 2, j2 = 4; j2 <= n; (j2 += j), (j2 += ++j) ) {
if (factor_table[j].second == 1) {
int i = j;
int ij = j2;
while (ij <= n) {
factor_table[ij] = std::pair<int, int>(j, i);
++i;
ij += j;
}
}
}
}
std::vector<unsigned> powers;
template<int dir>
void factor( int num )
{
while (num != 1) {
powers[factor_table[num].first] += dir;
num = factor_table[num].second;
}
}
template<unsigned N>
void calc_combinations(unsigned (&bin_sizes)[N])
{
using std::swap;
powers.resize(0);
if (N < 2) return;
unsigned& largest = bin_sizes[0];
size_t sum = largest;
for( int bin = 1; bin < N; ++bin ) {
unsigned& this_bin = bin_sizes[bin];
sum += this_bin;
if (this_bin > largest) swap(this_bin, largest);
}
fill_sieve(sum);
powers.resize(sum+1);
for( unsigned i = largest + 1; i <= sum; ++i ) factor<+1>(i);
for( unsigned bin = 1; bin < N; ++bin )
for( unsigned j = 2; j <= bin_sizes[bin]; ++j ) factor<-1>(j);
}
#include <iostream>
#include <cmath>
int main(void)
{
unsigned bin_sizes[] = { 8, 1, 18, 19, 10, 10, 7, 18, 7, 2, 16, 8, 5, 8, 2, 3, 19, 19, 12, 1, 5, 7, 16, 0, 1, 3, 13, 15, 13, 9, 11, 6, 15, 4, 14, 4, 7, 13, 16, 2, 19, 16, 10, 9, 9, 6, 10, 10, 16, 16 };
calc_combinations(bin_sizes);
char* sep = "";
for( unsigned i = 0; i < powers.size(); ++i ) {
if (powers[i]) {
std::cout << sep << i;
sep = " * ";
if (powers[i] > 1)
std::cout << "**" << powers[i];
}
}
std::cout << "\n\n";
}
The definition of N choose R is to compute the two products and divide one with the other,
(N * N-1 * N-2 * ... * N-R+1) / (1 * 2 * 3 * ... * R)
However, the multiplications may become too large really quick and overflow existing data type. The implementation trick is to reorder the multiplication and divisions as,
(N)/1 * (N-1)/2 * (N-2)/3 * ... * (N-R+1)/R
It's guaranteed that at each step the results is divisible (for n continuous numbers, one of them must be divisible by n, so is the product of these numbers).
For example, for N choose 3, at least one of the N, N-1, N-2 will be a multiple of 3, and for N choose 4, at least one of N, N-1, N-2, N-3 will be a multiple of 4.
C++ code given below.
int NCR(int n, int r)
{
if (r == 0) return 1;
/*
Extra computation saving for large R,
using property:
N choose R = N choose (N-R)
*/
if (r > n / 2) return NCR(n, n - r);
long res = 1;
for (int k = 1; k <= r; ++k)
{
res *= n - k + 1;
res /= k;
}
return res;
}
A nice way to implement n-choose-k is to base it not on factorial, but on a "rising product" function which is closely related to the factorial.
The rising_product(m, n) multiplies together m * (m + 1) * (m + 2) * ... * n, with rules for handling various corner cases, like n >= m, or n <= 1:
See here for an implementation nCk as well as nPk as a intrinsic functions in an interpreted programming language written in C:
static val rising_product(val m, val n)
{
val acc;
if (lt(n, one))
return one;
if (ge(m, n))
return one;
if (lt(m, one))
m = one;
acc = m;
m = plus(m, one);
while (le(m, n)) {
acc = mul(acc, m);
m = plus(m, one);
}
return acc;
}
val n_choose_k(val n, val k)
{
val top = rising_product(plus(minus(n, k), one), n);
val bottom = rising_product(one, k);
return trunc(top, bottom);
}
val n_perm_k(val n, val k)
{
return rising_product(plus(minus(n, k), one), n);
}
This code doesn't use operators like + and < because it is type generic (the type val represents a value of any kinds, such as various kinds of numbers including "bignum" integers) and because it is written in C (no overloading), and because it is the basis for a Lisp-like language that doesn't have infix syntax.
In spite of that, this n-choose-k implementation has a simple structure that is easy to follow.
Legend: le: less than or equal; ge: greater than or equal; trunc: truncating division; plus: addition, mul: multiplication, one: a val typed constant for the number one.
the line
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
should be
else return (n*fact(n-1))/(fact(r)*fact(n-r));
or even
else return fact(n)/(fact(r)*fact(n-r));
Use double instead of int.
UPDATE:
Your formula is also wrong. You should use fact(n)/fact(r)/fact(n-r)
this is for reference to not to get time limit exceeded while solving nCr in competitive programming,i am posting this as it will be helpful to u as you already got answer for ur question,
Getting the prime factorization of the binomial coefficient is probably the most efficient way to calculate it, especially if multiplication is expensive. This is certainly true of the related problem of calculating factorial (see Click here for example).
Here is a simple algorithm based on the Sieve of Eratosthenes that calculates the prime factorization. The idea is basically to go through the primes as you find them using the sieve, but then also to calculate how many of their multiples fall in the ranges [1, k] and [n-k+1,n]. The Sieve is essentially an O(n \log \log n) algorithm, but there is no multiplication done. The actual number of multiplications necessary once the prime factorization is found is at worst O\left(\frac{n \log \log n}{\log n}\right) and there are probably faster ways than that.
prime_factors = []
n = 20
k = 10
composite = [True] * 2 + [False] * n
for p in xrange(n + 1):
if composite[p]:
continue
q = p
m = 1
total_prime_power = 0
prime_power = [0] * (n + 1)
while True:
prime_power[q] = prime_power[m] + 1
r = q
if q <= k:
total_prime_power -= prime_power[q]
if q > n - k:
total_prime_power += prime_power[q]
m += 1
q += p
if q > n:
break
composite[q] = True
prime_factors.append([p, total_prime_power])
print prime_factors
Recursive function is used incorrectly here. fact() function should be changed into this:
int fact(int n){
if(n==0||n==1) //factorial of both 0 and 1 is 1. Base case.
{
return 1;
}else
return (n*fact(n-1));//recursive call.
};
Recursive call should be made in else part.
NCR() function should be changed into this:
int NCR(int n,int r){
if(n==r) {
return 1;
} else if (r==0&&n!=0) {
return 1;
} else if(r==1)
{
return n;
}
else
{
return fact(n)/(fact(r)*fact(n-r));
}
};
// CPP program To calculate The Value Of nCr
#include <bits/stdc++.h>
using namespace std;
int fact(int n);
int nCr(int n, int r)
{
return fact(n) / (fact(r) * fact(n - r));
}
// Returns factorial of n
int fact(int n)
{
int res = 1;
for (int i = 2; i <= n; i++)
res = res * i;
return res;
}
// Driver code
int main()
{
int n = 5, r = 3;
cout << nCr(n, r);
return 0;
}
I have built recursive function to compute Pascal's triangle values.
Is there a way to optimize it?
Short reminder about Pascal's triangle: C(n, k) = C(n-1, k-1) + C(n-1, k)
My code is:
int Pascal(int n, int k) {
if (k == 0) return 1;
if (n == 0) return 0;
return Pascal(n - 1, k - 1) + Pascal(n - 1, k);
}
The inefficiency I see is that it stores some values twice.
Example:
C(6,2) = C(5,1) + C(5,2)
C(6,2) = C(4,0) + C(4,1) + C(4,1) + C(4,2)
it will call C(4,1) twice
Any idea how to optimize this function?
Thanks
The following routine will compute the n-choose-k, using the recursive definition and memoization. The routine is extremely fast and accurate:
inline unsigned long long n_choose_k(const unsigned long long& n,
const unsigned long long& k)
{
if (n < k) return 0;
if (0 == n) return 0;
if (0 == k) return 1;
if (n == k) return 1;
if (1 == k) return n;
typedef unsigned long long value_type;
class n_choose_k_impl
{
public:
n_choose_k_impl(value_type* table,const value_type& dimension)
: table_(table),
dimension_(dimension / 2)
{}
inline value_type& lookup(const value_type& n, const value_type& k)
{
const std::size_t difference = static_cast<std::size_t>(n - k);
return table_[static_cast<std::size_t>((dimension_ * n) + ((k < difference) ? k : difference))];
}
inline value_type compute(const value_type& n, const value_type& k)
{
// n-Choose-k = (n-1)-Choose-(k-1) + (n-1)-Choose-k
if ((0 == k) || (k == n))
return 1;
value_type v1 = lookup(n - 1,k - 1);
if (0 == v1)
v1 = lookup(n - 1,k - 1) = compute(n - 1,k - 1);
value_type v2 = lookup(n - 1,k);
if (0 == v2)
v2 = lookup(n - 1,k) = compute(n - 1,k);
return v1 + v2;
}
value_type* table_;
const value_type dimension_;
};
static const std::size_t static_table_dim = 100;
static const std::size_t static_table_size = static_cast<std::size_t>((static_table_dim * static_table_dim) / 2);
static value_type static_table[static_table_size];
static bool static_table_initialized = false;
if (!static_table_initialized && (n <= static_table_dim))
{
std::fill_n(static_table,static_table_size,0);
static_table_initialized = true;
}
const std::size_t table_size = static_cast<std::size_t>(n * (n / 2) + (n & 1));
unsigned long long dimension = static_table_dim;
value_type* table = 0;
if (table_size <= static_table_size)
table = static_table;
else
{
dimension = n;
table = new value_type[table_size];
std::fill_n(table,table_size,0LL);
}
value_type result = n_choose_k_impl(table,dimension).compute(n,k);
if (table != static_table)
delete [] table;
return result;
}
Keep a table of previously returned results (indexed by their n and k values); the technique used there is memoization. You can also change the recursion to an iteration and use dynamic programming to fill in an array containing the triangle for n and k values smaller than the one you are trying to evaluate, then just get one element from it.