Factorial modulo some number - algorithm

In order to calculate factorial for each and every number until some large number modulo some number and store in an array that is 1 to n(10000000).There is a naive process I have been trying, iterating for each and every number and calculating it and taking modulo and using the previous calculated result.Is there any good algorithm for performing this in order to get fastest execution time? Code which I have tried is as follows:
int a[10000000]={};
int m;//some large number
a[0] = a[1] = 0;
for(int i = 2; i < 10000000; i++)
{
a[i] = a[i] % m;
}

If the modulus m is less than or equal to the factorial argument n, then n! = 0 mod m
(because m will be a divisor of n!).

Related

Is this sieve really O(n)?

Can anyone please tell me how this is working in O(n).
http://www.geeksforgeeks.org/sieve-eratosthenes-0n-time-complexity/
void manipulated_seive(int N)
{
// 0 and 1 are not prime
isprime[0] = isprime[1] = false ;
// Fill rest of the entries
for (long long int i=2; i<N ; i++)
{
// If isPrime[i] == True then i is
// prime number
if (isprime[i])
{
// put i into prime[] vector
prime.push_back(i);
// A prime number is its own smallest
// prime factor
SPF[i] = i;
}
// Remove all multiples of i*prime[j] which are
// not prime by making isPrime[i*prime[j]] = false
// and put smallest prime factor of i*Prime[j] as prime[j]
// [ for exp :let i = 5 , j = 0 , prime[j] = 2 [ i*prime[j] = 10 ]
// so smallest prime factor of '10' is '2' that is prime[j] ]
// this loop run only one time for number which are not prime
for (long long int j=0;
j < (int)prime.size() &&
i*prime[j] < N && prime[j] <= SPF[i];
j++)
{
isprime[i*prime[j]]=false;
// put smallest prime factor of i*prime[j]
SPF[i*prime[j]] = prime[j] ;
}
}
}
I think the outer loop will run O(n) time and inner loop will run O(number of primes less than N) in case of prime numbers and O(1) in case of composite. But overall is should be O(n) * O(number of primes less than n). Am i missing something?
Thanks in advance.
The key idea is that each integer between 2 and n is encountered exactly once in the SPF calculation, thus the total number of iterations of the innermost loop is O(n).
The innermost loop fills the SPF array which indicates the smallest prime factor, for each integer between 2 and n.
Indeed, to compute the SPF array, each integer k between 2 and n is represented as k = i*prime[j], where prime[j] is a prime number below all prime factors of i (this is ensured by the prime[j] <= SPF[i] condition which would break the loop otherwise). This means that prime[j] is the smallest prime factor of k. But this representation is unique for each k (i.e. the same k won't be encountered once again, as another k = i2 * prime[j2] factorization, because if prime[j2] is not equal to prime[j] then one of them would not be the smallest prime factor of k). Thus each number k between 2 and n appears exactly once as the product i*prime[j], computed in the innermost loop.

Boolean matrix multiplication algorithm

This is my first question on stackoverflow. I've been solving some exercises from "Algorithm design" by Goodrich, Tamassia. However, I'm quite clueless about this problem. Unusre where to start from and how to proceed. Any advice would be great. Here's the problem:
Boolean matrices are matrices such that each entry is 0 or 1, and matrix multiplication is performed by using AND for * and OR for +. Suppose we are given two NxN random Boolean matrices A and B, so that the probability that any entry
in either is 1, is 1/k. Show that if k is a constant, then there is an algorithm for multiplying A and B whose expected running time is O(n^2). What if k is n?
Matrix multiplication using the standard iterative approach is O(n3), because you have to iterate over n rows and n columns, and for each element do a vector multiply of one of the rows and one of the columns, which takes n multiplies and n-1 additions.
Psuedo code to multiply matrix a by matrix b and store in matrix c:
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
int sum = 0;
for(m = 0; m < n; m++)
{
sum += a[i][m] * b[m][j];
}
c[i][j] = sum;
}
}
For a boolean matrix, as specified in the problem, AND is used in
place of multiplication and OR in place of addition, so it becomes
this:
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
boolean value = false;
for(m = 0; m < n; m++)
{
value ||= a[i][m] && b[m][j];
if(value)
break; // early out
}
c[i][j] = value;
}
}
The thing to notice here is that once our boolean "sum" is true, we can stop calculating and early out of the innermost loop, because ORing any subsequent values with true is going to produce true, so we can immediately know that the final result will be true.
For any constant k, the number of operations before we can do this early out (assuming the values are random) is going to depend on k and will not increase with n. At each iteration there will be a (1/k)2 chance that the loop will terminate, because we need two 1s for that to happen and the chance of each entry being a 1 is 1/k. The number of iterations before terminating will follow a Geometric distribution where p is (1/k)2, and the expected number of "trials" (iterations) before "success" (breaking out of the loop) doesn't depend on n (except as an upper bound for the number of trials) so the innermost loop runs in constant time (on average) for a given k, making the overall algorithm O(n2). The Geometric distribution formula should give you some insight about what happens if k = n. Note that in the formula given on Wikipedia k is the number of trials.

number of subarrays where sum of numbers is divisible by K

Given an array, find how many such subsequences (does not require to be contiguous) exist where sum of elements in that subarray is divisible by K.
I know an approach with complexity 2^n as given below. it is like finding all nCi where i=[0,n] and validating if sum is divisible by K.
Please provide Pseudo Code something like linear/quadratic or n^3.
static int numways = 0;
void findNumOfSubArrays(int [] arr,int index, int sum, int K) {
if(index==arr.length) {
if(sum%k==0) numways++;
}
else {
findNumOfSubArrays(arr, index+1, sum, K);
findNumOfSubArrays(arr, index+1, sum+arr[index], K);
}
}
Input - array A in length n, and natural number k.
The algorithm:
Construct array B: for each 1 <= i <= n: B[i] = (A[i] modulo K).
Now we can use dynamic programming:
We define D[i,j] = maximum number of sub-arrays of - B[i..n] that the sum of its elements modulo k equals to j.
1 <= i <= n.
0 <= j <= k-1.
D[n,0] = if (b[n] == 0), 2. Otherwise, 1.
if j > 0 :
D[n,j] = if (B[n] modulo k) == j, than 1. Otherwise, 0.
for i < n and 0 <= j <= k-1:
D[i,j] = max{D[i+1,j], 1 + D[i+1, D[i+1,(j-B[i]+k) modulo k)]}.
Construct D.
Return D[1,0].
Overall running time: O(n*k)
Acutally, I don't think this problem can likely be solved in O(n^3) or even polynomial time, if the range of K and the range of numbers in array is unknown. Here is what I think:
Consider the following case: the N numbers in arr is something like
[1,2,4,8,16,32,...,2^(N-1)]
,
in this way, the sums of 2^N "subarrays" (that does not require to be contiguous) of arr, is exactly all the integer numbers in [0,2^N)
and asking how many of them is divisible by K, is equivalent to asking how many of integers are divisible by K in [0, 2^N).
I know the answer can be calculated directly like (2^N-1)/K (or something) in the above case. But , if we just change a few ( maybe 3? 4? ) numbers in arr randomly, to "dig some random holes" in the perfect-contiguous-integer-range [0,2^N), that makes it looks impossible to calculate the answer without going through almost every number in [0,2^N).
ok just some stupid thoughts ... could be totally wrong.
Use an auxiliary array A
1) While taking input, store the current grand total in the corresponding index (this executes in O(n)):
int sum = 0;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
sum += arr[i];
A[i] = sum;
}
2) now,
for (int i = 0; i < n; i++)
for (int j = i; j < n; j++)
check that (A[j] - A[i] + arr[i]) is divisible by k
There you go: O(n^2)...

Algorithm to find high/low numbers with at most 1.5n comparisons

I've been thinking about this homework question for a bit now. Given an number array of size n, design an algorithm that will find the high and and low values with at most 1.5n comparisons.
My first try was
int high=0
int low= Number.MaxValue //problem statement is unclear on what type of number to use
Number numList[0 . . n] //number array, assuming unsorted
for (i=0, i < n, i++) {
if (numList[i] > high)
high = numList[i]
else if (numList[i] < low)
low = numList[i]
}
My problem is each iteration of the loop has one of three possibilities:
low value is found - 1 comparison made
high value is found - 2 comparisons made
neither is found - 2 comparisons made
So for an entire array traversal, a maximum of 2n comparisons can be made, which is a far cry from the problem maximum requirement of 1.5n comparisons.
Start with a pairs of numbers and find local min and max (n/2 comparisons). Next, find global max from n/2 local maxes (n/2 comparisons), and similarly global min from local mins (n/2 comparisons). Total comparisons: 3*n/2 !
For i in 0 to n/2: #n/2 comparisons
if x[2*i]>x[2*i+1]:
swap(x,2*i,2*i+1)
global_min = min( x[0], x[2], ...) # n/2 comparisons
global_max = max( x[1], x[3], ...) # n/2 comparisons
Note that the above solution changes the array. Alternate solution:
Initialize min and max
For i = 0 to n/2:
if x[2*i]<x[2*i+1]:
if x[2*i]< min:
min = x[2*i]
if x[2*i+1]> max:
max = x[2*i+1]
else:
if x[2*i+1]< min:
min = x[2*i+1]
if x[2*i]> max:
max = x[2*i]
I know this has already been answered, but in case someone is looking for another way to think about this. This answer is similar to Lester's, but can handle odd values of n without breaking and will still make at most 1.5n comparisons. The secret is in the modulus. ;)
As a side effect of ensuring we place the last value in the proper sub array, the second element in the givenList will be compared and placed twice. However, since we are not changing the original array and we are only interested in the high and low of the set, this does not really make a difference.
Initialize lowArray and highArray
Initialize subArrayCounter to 0
For i = 0; i < n; i+=2
X = givenList[i];
Y = givenList[(i+1)%n];
If(x < y)
lowArray[subArrayCounter] = x;
highArray[subArrayCounter] = y;
subArrayCounter++;
else
lowArray[subArrayCounter] = y;
highArray[subArrayCounter] = x;
subArrayCounter++;
Initialize low to lowArray[0];
Initialize high to highArray[0];
For i = 1; i < lowArray.length; i++
If(lowArray[i] < low)
Low = lowArray[i];
For i = 1; i < highArray.length; i++
If(highArray[i] > high)
High = highArray[i]
This is the same answer as ElKamina but as I had already started writing the pseudo code I thought I'd finish and post it.
The idea is to compare pairs of values (n/2 comparisons) to get an array of high values and an array of low values. With each of those arrays we again compare pairs of values (2 * n/2 comparisons) to get the highest and lowest values respectively.
n/2 + 2*n/2 = 1.5n comparisons
Here's the pseudocode:
int[] highNumList;
int[] lowNumList;
for (i = 0, i < n, i+=2)
{
a = numList[i];
b = numList[i+1];
if (a > b)
{
highNumList.Add(a);
lowNumlist.Add(b);
}
else
{
highNumlist.Add(b);
lowNumList.Add(a);
}
}
int high = highNumList[0];
int low = lowNumList[0];
for (i = 0, i < n/2, i+=2)
{
if (highNumList[i] < highNumList[i+1])
high = highNumList[i+1]
if (lowNumList[i] > lowNumList[i+1])
low = lowNumList[i+1]
}
This code doesn't account for n not being even or the initial array being empty.
This is a question I had during an interview and I found the answer with a small hint from the interviewer which was "How do you compare two numbers?" (it really helped).
Here is the explanation:
Lets say I have 100 numbers (you can easily replace it by n but it work better for the example if n is an even number). What I do is that I split it into 50 lists of 2 numbers. For each couple I make one comparison and I'm done (which makes 50 comparisons by now) then I just have to find the minimum of the minimums (which is 49 comparisons) and the maximum of the maximums (which is 49 comparisons as well) such that we have to make 49+49+50=148 comparisons. We're done !
Remark: to find the minimum we proceed as follow (in pseudo code):
n = myList.size();
min = myList[0];
for (int i(1); i<n-1; i++)
{
if (min>myList[i]) min = myList[i];
}
return min;
And we find it in (n-1) comparisons. The code is almost the same for maximum.

Sum of the largest odd divisors of the first n numbers

I've been working on topcoder recently and I stumbled upon this question which I can't quite make understand.
The question is to find F(n) = f(1)+f(2)+....+f(n) for a given "n" such that f(n) is the largest odd divisor for n.
There are many trivial solutions for the answer; however, I found this solution very intriguing.
int compute(n) {
if(n==0) return 0;
long k = (n+1)/2;
return k*k + compute(n/2);
}
However, I don't quite understand how to obtain a recursive relation from a problem statement such as this. Could someone help out?
I believe they are trying to use the following facts:
f(2k+1) = 2k+1, i.e. the largest odd divisor of an odd number is the number itself.
f(2k) = f(k). i.e the largest odd divisor of an even number 2m is same as the largest odd divisor of the number m.
Sum of first k odd numbers is equal to k^2.
Now split {1,2,..., 2m+1} as {1,3,5,7,...} and {2,4,6,...,2m} and try to apply the above facts.
You can use dynamic approach also using auxiliary spaces
int sum=0;
int a[n+1];
for(int i=1;i<=n;i++){
if(i%2!=0)
a[i] = i;
else
a[i] = a[i/2];
}
for(int i=1;i<=n;i++){
sum+=a[i];
}
cout<<sum;
As when number is odd then the number itself will be the greatest odd divisor and a[i] will store it's value and when number is even then the a[number/2] will be stored in a[i] because for even number the greatest odd divisor of number/2 will be the greatest odd divisor of the number.
It can also be solved using three cases when number is odd then add number itself else if number is power of 2 then add 1 else if number is even except power of 2 divide it by 2 till you get odd and add that odd to sum.
I cannot see how that algorithm could possible work for the problem you described. (I'm going to assume that "N" and "n" refer to the same variable).
Given n = 12.
The largest odd divisor is 3 (the others are 1, 2, 4, 6 & 12)
F(12) is therefor f(1) + f(2) + f(3) or 1 + 1 + 3 or 5.
Using this algorithm:
k = (12+1)/2 or 6
and we return 6 * 6 + f(6), or 36 + some number which is not going to be negative 31.
if this were Java, I'd say:
import java.util.*;
int sum_largest_odd_factors (int n){
ArrayList<Integer> array = new ArrayList();//poorly named, I know
array.add(1);
for(int j = 2; j <= n; j++){
array.add(greatestOddFactor(j));
}
int sum = 0;
for(int i = 0; i < array.size(); i++){
sum += array.get(i);
}
return sum;
}
int greatestOddFactor(int n){
int greatestOdd = 1;
for(int i = n-((n%2)+1); i >= 1; i-=2){
//i: starts at n if odd or n-1 if even
if(n%i == 0){
greatestOdd = i;
break;
//stop when reach first odd factor b/c it's the largest
}
}
return greatestOdd;
}
This is admittedly tedious and probably an O(n^2) operation, but will work every time. I'll leave it to you to translate to C++ as Java and J are the only languages I can work with (and even that on a low level). I'm curious as to what ingenious algorithms other people can come up with to make this much quicker.
IF u are looking for sum of all the odd divisors till n..
Sum of the all odd divisors of the first n numbers
...
for(long long int i=1;i<=r;i=i+2)
{
sum1=sum1+i*(r/i);
}
for sum of all divisors in a range l to r
for(long long int i=1;i<=r;i=i+2)
{
sum1=sum1+i*(r/i);
}
for(long long int i=1;i<l;i=i+2)
{
sum2=sum2+i*((l-1)/i);
}
ans=sum1-sum2;;;
THANK YOU!!

Resources