why a heap node of index i (starting from 1) and its height h satisfy (2^h)*i <= n < (2^(h+1)*i) where n is the heap size? - heap

why a heap node of index i (starting from 1) and its height h satisfy (2^h)*i <= n < (2^(h+1)*i) where n is the heap size?

Case N:1
2^h <= 1 <= 2^(h+1)
Note height of node is log(n) = log(1) = 0
= 2^0 <= 1 <= 2^(0+1)
= 1 <= 1 <= 2
So you can see its true for case n = 1
Let replace h = log(n) into the original question
= 2^h <= n <= 2^(h+1)
= 2^(log(n)) <= n <= 2^(log(n)+1) #replace n = log(n)
= n <= n <= 2^log(n) * 2^1 #exponents property
= n <= n <= 2n
Note the index 'i' cancels out if we divide by 'i' on each side.

Related

The Solution About Foobar Challenge "Find The Access Code"

I am challenging google foobar currently and met this question.
A "lucky triple" is a tuple (x, y, z) where x divides y and y divides z, such as (1, 2, 4).
Write a function solution(l) that takes a list of positive integers l and counts the number of "lucky triples" of (li, lj, lk) where the list indices meet the requirement i < j < k. The length of l is between 2 and 2000 inclusive. The elements of l are between 1 and 999999 inclusive. The solution fits within a signed 32-bit integer. Some of the lists are purposely generated without any access codes to throw off spies, so if no triples are found, return 0.
I have try some other method and keep failing on the 5th test. Somehow I found solution from Google Foobar Challenge 3 - Find the Access Codes , but I don't understand why my code don't work.
Here's the code that I refer the method from "Find the access codes" Google Foobar challenge
def solution(l):
i = 0
indexes = []
inputSize = len(l)
keyCounter = 0
while i < inputSize-1:
temp = i+1
matches = []
while temp < inputSize:
if(l[temp] % l[i] == 0):
matches.append(temp)
temp +=1
indexes.append(matches)
i+=1
m = 0
while m < len(indexes):
n=0
temp = indexes[m]
while n < len(temp)-1:
keyCounter += len(list(set(indexes[m]).intersection(indexes[temp[n]])))
n +=1
m+=1
return keyCounter
and my original attemps :
def solution(l):
i = 0
j = 1
k = 2
keyCounter = 0
while i < len(l)-2:
if(l[j] % l[i] == 0):
if(l[k] % l[j] == 0):
keyCounter +=1
if(k < len(l)-1):
k += 1
elif(j < len(l)-2):
j += 1
k = j + 1
else:
i += 1
j = i + 1
k = j + 1
else:
if(j < len(l)-2):
j += 1
k = j + 1
else:
i += 1
j = i + 1
k = j + 1
return keyCounter

Rabin Karp Algorithm Negative Hash

I have this Rabin Karp implementation. Now the only thing I'm doing for rolling hash is subtract power*source[i] from the sourceHash. power is 31^target.size()-1 % mod
But I can't understand why we're adding mod to sourceHash when it becomes negative. I have tried adding other values but it doesn't work and it only works when we add mod. Why is this? Is there a specific reason why we're adding mod and not anything else (like a random big number for example).
int rbk(string source, string target){
int m = target.size();
int n = source.size();
int mod = 128;
int prime = 11;
int power = 1;
int targetHash = 0, sourceHash = 0;
for(int i = 0; i < m - 1; i++){
power =(power*prime) % mod;
}
for(int i = 0; i < target.size(); i++){
sourceHash = (sourceHash*prime + source[i]) % mod;
targetHash = (targetHash*prime + target[i]) % mod;
}
for(int i = 0; i < n-m+1; i++){
if(targetHash == sourceHash){
bool flag = true;
for(int j = 0; j < m; j++){
if(source[i+j] != target[j]){
flag = false;
break;
}
}
if(flag){
return 1;
}
}
if(i < n-m){
sourceHash = (prime*(sourceHash - source[i]*power) + source[i+m]) % mod;
if(sourceHash < 0){
sourceHash += mod;
}
}
}
return -1;
}
When using modulo arithmetics (mod n) we have just n distinct numbers: 0, 1, 2, ..., n - 1.
All the other numbers which out of 0 .. n - 1 are equal to some number in 0 .. n - 1:
-n ~ 0
-n + 1 ~ 1
-n + 2 ~ 2
...
-2 ~ n - 2
-1 ~ n - 1
or
n ~ 0
n + 1 ~ 1
n + 2 ~ 2
...
2 * n ~ 0
2 * n + 1 ~ 0
In general case A ~ B if and only if (A - B) % n = 0 (here % stands for remainder).
When implementing Rabin Karp algorithm we can have two potential problems:
Hash can be too large, we can face integer overflow
Negative remainder can be implemented in different way on different compilers: -5 % 3 == -2 == 1
To deal with both problems, we can normalize remainder and operate with numbers within safe 0 .. n - 1 range only.
For arbitrary value A we can put
A = (A % n + n) % n;

Is there an efficient way to generate number of factors of N less than X?

I am a beginner in the field of programming. I just want to find the number of factors / divisors of a positive integer N less than X. (X itself is a factor of N). I have a naive approach which doesn't work good for queries on N,X.
Here is my approach
int Divisors(int n, int x) {
int ans = 0;
if (x < sqrt(n)) {
for (int i = 1; i < x; i++) {
if (n % i == 0) {
ans++;
}
}
} else
for (int i = 1; i <= sqrt(n); i++) {
if (n % i == 0) {
if (n / i == i && i < x)
ans++;
else {
if (i < x)
ans++;
if (n / i < x)
ans++;
}
}
}
return ans;
}
Is there some efficient way to do this? Kindly help me out!
The actual problem I'm trying to solve :
Given some M and N I need to iterate through all positive integers less than or equal to N(1 <= i <= N) and I need to count how many numbers less than the current number (i) exists such that they divide the last multiple of i that is less than or equal to M (i.e., M - M % i) and finally find the sum of all counts.
Example
Given N = 5 and M = 10
Ans : 6
Explanation :
i = 1 count = 0
i = 2 count = 1 (10 % 1 = 0)
i = 3 count = 1 (9 % 1 = 0)
i = 4 count = 2 (8 % 1 = 0, 8 % 2 = 0)
i = 5 count = 2 (10 % 1 = 0, 10 % 2 = 0)
Therefore sum of all counts = 6
The wording of the question is a bit confusing.
I'm assuming you are finding the size of the set of all factors/divisors, D, of a number n that are less than a number x, where x is a factor of n.
An easier way of doing this is to iterate from all numbers 1 through x, exclusive of x, and use the modulo operator %.
Code:
int NumOfDiv(int x, int n){
int count = 0;
for(int i=1; i<x; i++){
if(n % i == 0) //This indicates that i divides n, having a remainder of 0,
look up % as it is very useful with number theory
count++;
}
return count;
}
Example:
int TestNum = NumOfDiv(4,12)
TestNum would have the value of 3

Explanation of the algorithm to find a number 'm' made up of digits 0's and 1's which is divisible by the number n

Here's a piece of code from a udemy course that I am currently taking that uses the pigeon hole principle to find a number made up of 0's and 1's divisible by the number n.
void findNumber(int n) {
int cur_rem = 0;
for(int i = 1; i <= n; i++) {
cur_rem = (cur_rem * 10 + 1) % n;
if(cur_rem == 0) {
for(int j = 1; j <= i; j++)
cout << 1;
return;
}
if(fr[cur_rem] != 0) {
for(int j = 1; j <= i - fr[cur_rem]; j++)
cout << 1;
for(int j = 1; j <= fr[cur_rem]; j++)
cout << 0;
return;
}
fr[cur_rem] = i;
}
}
So, in this code we actually first take the numbers 1,11,111,...,111..1(n times) and see if they are divisible by the given integer n. If they are not divisible then we find the 2 numbers within 1,11,111,...111..1(n times) with the same remainder when divided by the number n and subtract them to get the number that is divisible by n. So, I understand the theory part but I did not understand one line of the code.
Can someone please explain to me this line of code: cur_rem = (cur_rem * 10 + 1) % n; how can we get the remainder of the current number by multiplying the remainder of the previous number by 10 and then adding 1 and then finding the mod by dividing the sum by the given integer n?
Suppose the last number 111... (we'll call it m), had remainder r.
m % n = r
m = kn + r
Now the next number, 111..., call it m', is one digit longer than m.
m' = 10 m + 1
m' % n = (10 m + 1) % n
= (10(kn + r) + 1) % n
= (10 kn + 10r + 1) % n
= ( 10r + 1) % n

Positive number which has no prime factor greater than k

I tried to create a function which takes two variables n and k.
The function returns the number of positive integers that have prime factors all less than or equal to k. The number of positive integers is limited by n which is the largest positive integer.
For example, if k = 4 and n = 10; the positive integers which have all prime factors less than or equal to 4 are 1, 2, 3, 4, 6, 8, 9, 12...(1 is always part for some reason even though its not prime) but since n is 10, 12 and higher numbers are ignored.
So the function will return 7. The code I wrote works for smaller values of n while it just keeps on running for larger values.
How can I optimize this code? Should I start from scratch and come up with a better algorithm?
int generalisedHammingNumbers(int n, int k)
{
vector<int>store;
vector<int>each_prime = {};
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= i; ++j)
{
if (i%j == 0 && is_prime(j))
{
each_prime.push_back(j); //temporary vector of prime factors for each integer(i)
}
}
for (int m = 0; m<each_prime.size(); ++m)
{
while(each_prime[m] <= k && m<each_prime.size()-1) //search for prime factor greater than k
{
++m;
}
if (each_prime[m] > k); //do nothing for prime factor greater than k
else store.push_back(i); //if no prime factor greater than k, i is valid, store i
}
each_prime = {};
}
return (store.size()+1);
}
bool is_prime(int x)
{
vector<int>test;
if (x != 1)
{
for (int i = 2; i < x; ++i)
{
if (x%i == 0)test.push_back(i);
}
if (test.size() == 0)return true;
else return false;
}
return false;
}
int main()
{
long n;
int k;
cin >> n >> k;
long result = generalisedHammingNumbers(n, k);
cout << result << endl;
}
Should I start from scratch and come up with a better algorithm?
Yes... I think so.
This seems to me a work for the Sieve of Eratosthenes.
So I propose to
1) create a std::vector<bool> to detect, through Eratosthenes, the primes to n
2) remove primes starting from k+1, and their multiples, from the pool of your numbers (another std::vector<bool>)
3) count the true remained values in the pool vector
The following is a full working example
#include <vector>
#include <iostream>
#include <algorithm>
std::size_t foo (std::size_t n, std::size_t k)
{
std::vector<bool> primes(n+1U, true);
std::vector<bool> pool(n+1U, true);
std::size_t const sqrtOfN = std::sqrt(n);
// first remove the not primes from primes list (Sieve of Eratosthenes)
for ( auto i = 2U ; i <= sqrtOfN ; ++i )
if ( primes[i] )
for ( auto j = i << 1 ; j <= n ; j += i )
primes[j] = false;
// then remove from pool primes, bigger than k, and multiples
for ( auto i = k+1U ; i <= n ; ++i )
if ( primes[i] )
for ( auto j = i ; j <= n ; j += i )
pool[j] = false;
// last count the true value in pool (excluding the zero)
return std::count(pool.begin()+1U, pool.end(), true);
}
int main ()
{
std::cout << foo(10U, 4U) << std::endl;
}
Generate the primes using a sieve of Erastothenes, and then use a modified coin-change algorithm to find numbers which are products of only those primes. In fact, one can do both simultaneously like this (in Python, but is easily convertible to C++):
def limited_prime_factors(n, k):
ps = [False] * (k+1)
r = [True] * 2 + [False] * n
for p in xrange(2, k+1):
if ps[p]: continue
for i in xrange(p, k+1, p):
ps[i] = True
for i in xrange(p, n+1, p):
r[i] = r[i//p]
return [i for i, b in enumerate(r) if b]
print limited_prime_factors(100, 3)
The output is:
[0, 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96]
Here, each time we find a prime p, we strike out all multiples of p in the ps array (as a standard Sieve of Erastothenes), and then in the r array, mark all multiples of any number that's a multiple of p whether their prime factors are all less than or equal to p.
It runs in O(n) space and O(n log log k) time, assuming n>k.
A simpler O(n log k) solution tests if all the factors of a number are less than or equal to k:
def limited_prime_factors(n, k):
r = [True] * 2 + [False] * n
for p in xrange(2, k+1):
for i in xrange(p, n+1, p):
r[i] = r[i//p]
return [i for i, b in enumerate(r) if b]
Here's an Eulerian version in Python (seems about 1.5 times faster than Paul Hankin's). We generate only the numbers themselves by multiplying a list by each prime and its powers in turn.
import time
start = time.time()
n = 1000000
k = 100
total = 1
a = [None for i in range(0, n+1)]
s = []
p = 1
while (p < k):
p = p + 1
if a[p] is None:
#print("\n\nPrime: " + str(p))
a[p] = True
total = total + 1
s.append(p)
limit = n / p
new_s = []
for i in s:
j = i
while j <= limit:
new_s.append(j)
#print j*p
a[j * p] = True
total = total + 1
j = j * p
s = new_s
print("\n\nGilad's answer: " + str(total))
end = time.time()
print(end - start)
# Paul Hankin's solution
def limited_prime_factors(n, k):
ps = [False] * (k+1)
r = [True] * 2 + [False] * n
for p in xrange(2, k+1):
if ps[p]: continue
for i in xrange(p, k+1, p):
ps[i] = True
for i in xrange(p, n+1, p):
r[i] = r[i//p]
return len([i for i, b in enumerate(r) if b]) - 1
start = time.time()
print "\nPaul's answer:" + str(limited_prime_factors(1000000, 100))
end = time.time()
print(end - start)