Tricky and confusing C program about divisor sum and perfect numbers - c

The assignment is :
Write a program that calculates the sum of the divisors of a number from input.
A number is considered perfect if the sum of it's divisiors equal the number (ex: 6 = 1+2+3 ;28 = 1 + 2 + 4 + 7 +14).
Another definition:
a perfect number is a number that is half the sum of all of its positive divisors (including itself)
Generate the first k perfect numbers (k<150).
The main problem with this is that it's confusing the two asking points don't really relate.
In this program i calculated the sum of divisors of an entered number, but i don't know how to relate it with the second point (Generate the first k perfect numbers (k<150)).
#include <stdio.h>
#include <stdlib.h>
main()
{
int x,i,y,div,suma,k;
printf("Introduceti numarul\n"); \\enter the number
scanf("%d",&x);
suma=0; \\sum is 0
for(i=1;i<=x;i++)
{
if(x%i==0)
suma=suma+i; \\sum=sum+i;
}
printf("Suma divizorilor naturali este: %d\n",suma); \\the sum of the divisors is
for(k=1;k<150;k++) \\ bad part
{
if (x==suma)
printf("%d",k);
}
}

Suppose you have a function which can tell whether a given integer is perfect or not:
int isPerfect(int);
(function body not shown)
Now your main program will look like:
int candidate;
int perfectNumbers;
for(candidate = 1, perfectNumbers = 0; perfectNumbers < 150; candidate++) {
if (isPerfect(candidate)) {
printf("Number %d is perfect\n", candidate);
perfectNumbers++;
}
}
EDIT
For the same program without functions:
int candidate;
int perfectNumbers;
for(candidate = 1, perfectNumbers = 0; perfectNumbers < 150; candidate++) {
[... here your algorithm to compute the sum of the divisors of "candidate" ...]
if (candidate*2 == sum_of_divisors) {
printf("Number %d is perfect\n", candidate);
perfectNumbers++;
}
}
EDIT2: Just a note on perfect numbers
As noted in the comments section below, perfect numbers are very rare, only 48th of them are known as of 2014. The sequence (A000396) also grows very fast: using 64-bit integers you'll be able to compute up to the 8th perfect number (which happen to be 2,305,843,008,139,952,128). In this case the variable candidate will wrap around and start "finding" "new" perfect numbers from the beginning (until 150 of them are found: actually 19 repetitions of the only 8 findable in 64-bit integers). Note though that your algorithm must not choke on a candidate equals to 0 or to negative numbers (only to 0 if you declare candidate as unsigned int).

I am interpreting the question to mean generate all numbers under 150 that could are perfect numbers.
Therefore, if your program works for calculating perfect numbers, you keep calculating them until the starting number is >= 150.
Hope that makes sense.

Well, here's my solution ..
First, you have to make a reliable way of getting divisors.Here's a function I made for that:
size_t
getdivisors(num, divisors)
long long num;
long long *divisors;
{
size_t divs = 0;
for(long long i = num; i > 0; --i)
if (num%i == 0)
divisors[divs++] = i;
return divs;
}
Second, you need to check if the number's divisors match the perfect number's divisors properties (the sum of them is half the number).
Here's a second function for that:
bool
isperfect(num)
long long num;
{
long long divisors[num/2+1];
size_t divs = getdivisors(num, divisors);
if (divs == 0)
return false;
long long n = 0;
for(int i = 1; i < divs; ++i)
n += divisors[i];
return (n == num);
}
Now, from your question, I think you need to print all perfect numbers less than 150, right ?
See this:
int
main(argc, argv)
int argc;
char ** argv;
{
for(int i = 1; i < 150; ++i)
if (isperfect(i))
printf("%d is perfect.\n", i);
return 0;
}
I hope that answers your question ..

Related

Issues with using nested loops to find strong numbers between two user input numbers

So I am new to C, and have been doing some practice, and nested loops tend to be tougher for me.
This new problem about finding a strong number between two user input numbers is confusing me.
Essentially, a strong number is a number whose individual digit's factorials add up to the number. e.g. 145 = 1! + 4! + 5! = 1 + 24 + 120.
My issue is that after I input the two numbers, absolutely nothing happens. I am trying to print all strong numbers in between a range.
I have been trying to break the code down by pieces, and added comments to actually make it easier to understand for myself and others.
I am using the following function to find the strong numbers, the int main() just has the user input statements:
void strongno(int num1, int num2)
{
// num1 and num2 are from user input in the in main() function
int tot = 0; // to store the total number from each digits factorials
for(int i = num1; i < num2; i++)
//getting each individual number in the range, say i = 145
{
while(i)
{
int rem, fact = 1;
rem = i % 10;// I am using this to get each digit alone, so first we get 5
for(int j = 1; j <= rem; j++)
{
fact = fact * j;
//the fact will give us the factorial of 5 = 120
}
tot = tot + fact; //tot will add all of the factorials of each remainder
// while the number is not 0, so for now it is 120
i = i / 10; // this will give us 14, and the cycle will repeat
}
// Once we have our total, we will compare the actual number i
// to our calculated total. If it matches, it is a strong number
if(tot == i)
{
printf("Strong Number: %d\n", i);
}
else
{
continue;
}
}
}
I feel that the main issue may be with where I am actually placing the if statement or something, however I have tried arranging it and to no avail. The loops make sense to me, how they interact and all. I am trying not to look at the solution for this question, as that never helps, and would prefer guidance with the code I have, to work on a proper solution. Anything is appreciated.
For starters it is better to declare the function with parameters of the unsigned type unsigned int instead of the signed type int
void strongno( unsigned int num1, unsigned int num2);
Otherwise you will have problems with negative numbers.
Using this while loop
while(i)
does not make a sense because it changes the variable i used in the preceding for loop. You need to use some intermediate variable that will assigned with the value of i.
For example
for( ; num1 < num2; num1++)
//getting each individual number in the range, say i = 145
{
unsigned int i = num1;
//...
Also the variable tot should be declared and initialized where it is used that is within the outer for loop.
for( ; num1 < num2; num1++)
//getting each individual number in the range, say i = 145
{
unsigned int i = num1;
unsigned int tot = 0; // to store the total number from each digits factorials
//...
And this else statement
else
{
continue;
}
is just redundant. Remove it.

Sum digits of number [duplicate]

This question already has answers here:
Find the sum of digits of a number(in c)
(6 answers)
Closed 2 years ago.
Hello i need problem with this task in C language. If anyone had a similar problem it would help me.
The task is:
Write a program that loads the numbers a and b (a <b), then finds and prints the numbers from the segment of [a, b] and prints the sum of the digits of each number.
I wrote for three issues, for example:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n1,n2,sum=0,a,b,k,n3;
scanf("%d",&a);
scanf("%d",&b);
for(k=a;k<=b;k++)
{
n1=k%10;
n2=(k/10)%10;
n3=k/100;
sum=n1+n2+n3;
printf("%d\n",sum);
}
}
The problem arises when I enter a larger than three-digit number, how to make for any number, no matter if it is two-digit, three-digit, four-digit ...
Well the way you solve this issue depends on the exact requirements. Given that you only have ints here I would use the following though it is by no meand production code
int main() {
int a = whatever;
int b = whatever;
char* a_as_s = itoa(a);
char* b_as_s = itoa(b);
int sum_of_a = 0;
int sum_of_b = 0;
for(int i = 0; a_as_s[i]; i++)
sum_of_a += atoi(a_as_s[i]);
for(int i = 0; b_as_s[i]; i++)
sum_of_b += atoi(b_as_s[i]);
}
That should calculate the sum of digits for arbirary lengths - the rest of your code seems fine
You've already solved the iterating part so as people have suggested in the comments all you need now is a way to sum the digits of an arbitrary integer. I've modified your solution with my take on the problem. I'm pretty sure there is a more elegant/efficient way to do this, so I'd suggest you also check out the links people have provided in the comments. Anyhow here is my take:
#include <stdio.h>
int maxPowOf10(int num)
{
int divisor = 1;
for(;;)
{
if(num / divisor == 0)
{
break;
}
divisor *= 10;
}
return divisor / 10;
}
int sumOfDigits(int num)
{
int sum = 0;
for(int divisor = maxPowOf10(num); divisor >= 1; divisor /= 10)
{
int tmp = num / divisor;
sum += tmp;
num -= tmp * divisor;
}
return sum;
}
int main()
{
int n1,n2,sum=0,a,b,k,n3;
printf("Insert a: ");
scanf("%d",&a);
printf("Insert b: ");
scanf("%d",&b);
printf("Result\n");
for(k=a;k<=b;k++)
{
sum = sumOfDigits(k);
printf("number: %d sum of its digits: %d\n", k, sum);
}
return 0;
}
The approach is fairly straightforward. To find the sum of the digits, first you determine what is the largest power of 10 that still features in the number. Once that is found we can just divide by the largest power of 10 and add the result to sum. The trick is that, after that, we have to remove the part of the number that is described by the decimal place we are at. So we don't count it again. Then, you keep repeating the process for ever decreasing powers of 10. In the end you have the complete sum.
To illustrate this on 152 for example:
a) The largest power of 10 in 152 is 100.
b1) We divide 152 by 100 and get 1. We add 1 to sum. We also decrease the number to 52 (152 - 100)
b2) We divide 52 by 10 and get 5. We add 5 to sum. We decrease the number to 2 (52 - 50).
b3) We divide 2 by 1 and get 2. We add 2 to sum. We decrease the number to 0 (2 - 2).
Point a describes the method maxPowOf10
Point b describes the method sumOfDigits

Why does this prime number algorithm work?

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int anz;
scanf("%d", &anz);
time_t start = time(0);
int *primZ = malloc(anz * sizeof(int));
primZ[0] = 2;
int Num = 0;
for (int i = 1, num = 3; i < anz; num += 2) {
for (int j = 1; j < i; j++) {
if (num % primZ[j] == 0) {
num += 2;
j = 0;
}
//this part
if (primZ[j] > i / 2)
break;
}
primZ[i] = num;
i++;
printf("%d ,",num);
}
time_t delta = time(0) - start;
printf("%d", delta);
getchar();
getchar();
return 0;
}
The code works perfectly fine, the question is why. The part if(primZ[j] > i/2) makes the program 2 - 3 times faster. It was actually meant to be if(primZ[j] > num/3) which makes perfect sense because num can only be an odd number. But it is the number of found prime numbers. It makes no sense to me. Please explain.
You check if the prime is composite by checking if it divisible by already found prime numbers. But in doing so you only have to check up to and including the square root of the number because any number larger than that that divides the number will leave a smaller number than the square root of the number.
For example 33 is composite, but you only have to check numbers up to 5 to realize that, you don't need to check it being divisible by 11 because it leaves 3 (33/11=3) which we already checked.
This means that you could improve your algorithm by
for (int j = 1; j < i; j++) {
if( primZ[j]*primZ[j] > num )
break;
if (num % primZ[j] == 0) {
num += 2;
j = 0;
}
}
The reason you can get away with comparing with cutting of at i/2 is due to the distribution of the prime numbers. The prime counting function is approximately i = num/log(num) and then you get that i/2 > sqrt(num).
The reason is that the actual bound is much tighter than num/3 - you could use:
if (primZ[j] > sqrt(num))
The reason for that being that if a prime higher than the square root of num divides num, there must also be a lower prime that does (since the result of such a division must be lower than the square root).
This means that as long as i/2 is higher than sqrt(num), the code will work. What happens is that the number of primes lower than a number grows faster than the square root of that number, meaning that (completely accidentally) i/2 is a safe bound to use.
You can check out how your i value behaves here - they call it pi(x), the number of primes less than x.
It makes sense, since if n has two factors one of them is surely less than or equal to n/2, sense the program found no factors of i in primZ that are less than or equal to i/2 it means there's no factors of i -except 1 of course-.
Sense primZ is sorted in ascending order and j only increases, when primeZ[j] > i/2 it indicates that there's no factors of i in primZ that are less than i/2.
P.S.The point of starting the search is stated in the first part of the for statement num=3 , and the recurring statement num += 2 ensures you only test odd numbers

Counting number of primes within a given range of long int using C

Well, there are lots of such questions available in SO as well as other forums. However, none of these helped.
I wrote a program in "C" to find number of primes within a range. The range i in long int. I am using Sieve of Eratosthenes" algorithm. I am using an array of long ints to store all the numbers from 1 till the limit. I could not think of a better approach to achieve without using an array. The code works fine, till 10000000. But after that, it runs out of memory and exits. Below is my code.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef unsigned long uint_32;
int main() {
uint_32 i, N, *list, cross=0, j=4, k, primes_cnt = 0;
clock_t start, end;
double exec_time;
system("cls");
printf("Enter N\n");
scanf("%lu", &N);
list = (uint_32 *) malloc( (N+1) * sizeof(uint_32));
start = clock();
for(i=0; i<=N+1; i++) {
list[i] = i;
}
for(i=0; cross<=N/2; i++) {
if(i == 0)
cross = 2;
else if(i == 1)
cross = 3;
else {
for(j=cross+1; j<=N; j++) {
if(list[j] != 0){
cross = list[j];
break;
}
}
}
for(k=cross*2; k<=N; k+=cross) {
if(k <= N)
list[k] = 0;
}
}
for(i=2; i<=N; i++) {
if(list[i] == 0)
continue;
else
primes_cnt++;
}
printf("%lu", primes_cnt);
end = clock();
exec_time = (double) (end-start);
printf("\n%f", exec_time);
return 0;
}
I am stuck and can't think of a better way to achieve this. Any help will be hugely appreciated. Thanks.
Edit:
My aim is to generate and print all prime numbers below the range. As printing consumed a lot of time, I thought of getting the first step right.
There are other algorithm that does not require you to generate prime number up to N to count number of prime below N. The easiest algorithm to implement is Legendre Prime Counting. The algorithm requires you to generate only sqrt(N) prime to determine the number of prime below N.
The idea behind the algorithm is that
pi(n) = phi(n, sqrt(n)) + pi(sqrt(n)) - 1
where
pi(n) = number of prime below N
phi(n, m) = number of number below N that is not divisible by any prime below m.
That's mean phi(n, sqrt(n)) = number of prime between sqrt(n) to n. For how to calculate the phi, you can go to the following link (Feasible implementation of a Prime Counting Function)
The reason why it is more efficient is because it is easiest to compute phi(n, m) than to compute pi(n). Let say that I want to compute phi(100, 3) means that how many number below or equal to 100 that does not divisible by 2 and 3. You can do as following. phi(100, 3) = 100 - 100/2 - 100/3 + 100/6.
Your code uses about 32 times as much memory as it needs. Note that since you initialized list[i] = i the assignment cross = list[j] can be replaced with cross = j, making it possible to replace list with a bit vector.
However, this is not enough to bring the range to 264, because your implementation would require 261 bytes (2 exbibytes) of memory, so you need to optimize some more.
The next thing to notice is that you do not need to go up to N/2 when "crossing" the numbers: √N is sufficient (you should be able to prove this by thinking about the result of dividing a composite number by its divisors above √N). This brings memory requirements within your reach, because your "crossing" primes would fit in about 4 GB of memory.
Once you have an array of crossing primes, you can build a partial sieve for any range without keeping in memory all ranges that precede it. This is called the Segmented sieve. You can find details on it, along with a simple implementation, on the page of primesieve generator. Another advantage of this approach is that you can parallelize it, bringing the time down even further.
You can tweak the algorithm a bit to calculate the prime numbers in chunks.
Load a part of the array (as much as fits the memory), and in addition hold a list of all known prime numbers.
Whenever you load a chunk, first go through the already known prime numbers, and similar to the regular sieve, set all non primes as such.
Then, go over the array again, mark whatever you can, and add to the list the new prime numbers found.
When done, you'll have a list containing all your prime numbers.
I could see that the approach you are using is the basic implementation of Eratosthenes, that first stick out all the 2's multiple and then 3's multiple and so on.
But I have a better solution to the question. Actually, there is question on spoj PRINT. Please go through it and do check the constraints it follows. Below is my code snippet for this problem:
#include<stdio.h>
#include<math.h>
#include<cstdlib>
int num[46500] = {0},prime[5000],prime_index = -1;
int main() {
/* First, calculate the prime up-to the sqrt(N) (preferably greater than, but near to
sqrt(N) */
prime[++prime_index] = 2; int i,j,k;
for(i=3; i<216; i += 2) {
if(num[i] == 0) {
prime[++prime_index] = i;
for(j = i*i, k = 2*i; j<=46500; j += k) {
num[j] = 1;
}
}
}
for(; i<=46500; i+= 2) {
if(num[i] == 0) {
prime[++prime_index] = i;
}
}
int t; // Stands for number of test cases
scanf("%i",&t);
while(t--) {
bool arr[1000005] = {0}; int m,n,j,k;
scanf("%i%i",&m,&n);
if(m == 1)
m++;
if(m == 2 && m <= n) {
printf("2\n");
}
int sqt = sqrt(n) + 1;
for(i=0; i<=prime_index; i++) {
if(prime[i] > sqt) {
sqt = i;
break;
}
}
for(; m<=n && m <= prime[prime_index]; m++) {
if(m&1 && num[m] == 0) {
printf("%i\n",m);
}
}
if(m%2 == 0) {
m++;
}
for(i=1; i<=sqt; i++) {
j = (m%prime[i]) ? (m + prime[i] - m%prime[i]) : (m);
for(k=j; k<=n; k += prime[i]) {
arr[k-m] = 1;
}
}
for(i=0; i<=n-m; i += 2) {
if(!arr[i]) {
printf("%i\n",m+i);
}
}
printf("\n");
}
return 0;
}
I hope you got the point:
And, as you mentioned that your program is working fine up-to 10^7 but above it fails, it must be because you must be running out of the memory.
NOTE: I'm sharing my code only for knowledge purpose. Please, don't copy and paste it, until you get the point.

Prime Generator Algorithm

I've been trying to solve the SPOJ problem of Prime number Generator Algorithm.
Here is the question
Peter wants to generate some prime numbers for his cryptosystem. Help
him! Your task is to generate all prime numbers between two given
numbers!
Input
The input begins with the number t of test cases in a single line
(t<=10). In each of the next t lines there are two numbers m and n (1
<= m <= n <= 1000000000, n-m<=100000) separated by a space.
Output
For every test case print all prime numbers p such that m <= p <= n,
one number per line, test cases separated by an empty line.
It is very easy, but the online judge is showing error, I didn't get what the problem meant by 'test cases' and why that 1000000 range is necessary to use.
Here is my code.
#include<stdio.h>
main()
{
int i, num1, num2, j;
int div = 0;
scanf("%d %d", &num1, &num2);
for(i=num1; i<=num2; i++)
{
for(j=1; j<=i; j++)
{
if(i%j == 0)
{
div++;
}
}
if(div == 2)
{
printf("%d\n", i);
}
div = 0;
}
return 0;
}
I can't comment on the alogirthm and whether the 100000 number range allows optimisations but the reason that your code is invalid is because it doesn't seem to be parsing the input properly. The input will be something like:
2
123123123 123173123
987654321 987653321
That is the first line will give the number of sets of input you will get with each line then being a set of inputs. Your program, at a glance, looks like it is just reading the first line looking for two numbers.
I assume the online judge is just looking for the correct output (and possibly reasonable running time?) so if you correct for the right input it should work no matter what inefficiencies are in your algorithm (as others have started commenting on).
The input begins with the number t of test cases in a single line (t<=10)
you haven't got test cases in your programm.
Its wrong
And sorry for my English
2 - //the number of test cases
1 10 - // numbers n,m
3 5 - // numbers
Your programm will work only in first line.
#include <stdio.h>
#include <math.h>
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
unsigned int low,high,i=0,j=2,k,x=0,y=0,z;
unsigned long int a[200000],b[200000];
scanf("%d",&low);
scanf("%d",&high);
for(i=low;i<=high;i++)
a[x++]=i;
for(i=2;i<=32000;i++)
b[y++]=i;
i=0;
while(b[i]*b[i]<=high)
{
if(b[i]!=0)
{
k=i;
for(;k<y;k+=j)
{
if(k!=i)
{
b[k]=0;
}
}
}
i+=1;j+=1;
}
for(i=0;i<y;i++)
{
if(b[i]!=0 && (b[i]>=low && b[i]<=sqrt(high)))
printf("%d\n",b[i]);
}
int c=0;
for(i=0;i<y;i++)
{
if(b[i]!=0 && (b[i]>=1 && b[i]<=sqrt(high)))
b[c++]=b[i];
}
int m=a[0];
for(i=0;i<c;i++)
{
z=(m/b[i])*b[i];k=z-m;
if(k!=0)
k += b[i];
for(;k<x;)
{
if(a[k]!=0)
{
a[k]=0;
}
k+=b[i];
}
}
for(i=0;i<x;i++)
{
if(a[i]!=0 && (a[i]>=2 && a[i]<=(high)))
printf("%d\n",a[i]);
}
printf("\n");
}
return 0;
}
To find primes between m,n where 1 <= m <= n <= 1000000000, n-m<=100000, you need first to prepare the core primes from 2 to sqrt(1000000000) < 32000. Simple contiguous sieve of Eratosthenes is more than adequate for this. (Having sieved the core bool sieve[] array (a related C code is here), do make a separate array int core_primes[] containing the core primes, condensed from the sieve array, in an easy to use form, since you have more than one offset segment to sieve by them.)
Then, for each given separate segment, just sieve it using the prepared core primes. 100,000 is short enough, and without evens it's only 50,000 odds. You can use one pre-allocated array and adjust the addressing scheme for each new pair m,n. The i-th entry in the array will represent the number o + 2i where o is an odd start of a given segment.
See also:
Is a Recursive-Iterative Method Better than a Purely Iterative Method to find out if a number is prime?
Find n primes after a given prime number, without using any function that checks for primality
offset sieve of Eratoshenes
A word about terminology: this is not a "segmented sieve". That refers to the sieving of successive segments, one after another, updating the core primes list as we go. Here the top limit is known in advance and its square root is very small.
The same core primes are used to sieve each separate offset segment, so this may be better described as an "offset" sieve of Eratosthenes. For each segment being sieved, only the core primes not greater than its top limit's square root need be used of course; but the core primes are not updated while each such offset segment is sieved (updating the core primes is the signature feature of the "segmented" sieve).
For such small numbers you can simply search for all primes between 1 and 1000000000.
Take 62.5 mByte of RAM to create a binary array (one bit for each odd number, because we already know that no even number (except of 2) is a prime).
Set all bits to 0 to indicate that they are primes, than use a Sieve of Eratosthenes to set bits to 1 of all number that are not primes.
Do the sieve once, store the resulting list of numbers.
int num;
bool singleArray[100000];
static unsigned long allArray[1000000];
unsigned long nums[10][2];
unsigned long s;
long n1, n2;
int count = 0;
long intermediate;
scanf("%d", &num);
for(int i = 0; i < num; ++i)
{
scanf("%lu", &n1);
scanf("%lu", &n2);
nums[i][0] = n1;
nums[i][1] = n2;
}
for(int i = 0; i < 100000; ++i)
{
singleArray[i] = true;
}
for(int i = 0; i < num; ++i)
{
s = sqrt(nums[i][1]);
for(unsigned long k = 2; k <= s; ++k)
{
for (unsigned long j = nums[i][0]; j <= nums[i][1]; ++j)
{
intermediate = j - nums[i][0];
if(!singleArray[intermediate])
{
continue;
}
if((j % k == 0 && k != j) || (j == 1))
{
singleArray[intermediate] = false;
}
}
}
for(unsigned long m = nums[i][0]; m <= nums[i][1]; ++m)
{
intermediate = m - nums[i][0];
if(singleArray[intermediate])
{
allArray[count++] = m;
}
}
for(int p = 0; p < (nums[i][1] - nums[i][0]); ++p)
{
singleArray[p] = true;
}
}
for(int n = 0; n < count; ++n)
{
printf("%lu\n", allArray[n]);
}
}
Your upper bound is 10^9. The Sieve of Eratosthenes is O(N loglogN) which is too much for that bound.
Here are a few ideas:
Faster primality tests
The problem with a naive solution where you loop over the range [i, j] and check whether each number is prime is that it takes O(sqrt(N)) to test whether a number is prime which is too much if you deal with several cases.
However, you could try a smarter primality testing algorithm. Miller-Rabin is polynomial in the number of bits of N, and for N <= 10^9, you only need to check a = 2, 7 and 61.
Note that I haven't actually tried this, so I can't guarantee it would work.
Segmented sieve
As #KaustavRay mentioned, you could use a segmented sieve. The underlying idea is that if a number N is composite, then it has a prime divisor that is at most sqrt(N).
We use the Sieve of Eratosthenes algorithm to find the prime numbers below 32,000 (roughly sqrt(10^9)), and then for each number in the range [i, j] check whether there is any prime below 32,000 that divides it.
By the prime number theorem about one in log(N) numbers are prime which is small enough to squeeze in the time limit.
#include <iostream>
using namespace std;
int main() {
// your code here
unsigned long int m,n,i,j;int N;
cin>>N;
for(;N>0;N--)
{
cin>>m>>n;
if(m<3)
switch (n)
{
case 1: cout<<endl;continue;
case 2: cout<<2<<endl;
continue;
default:cout<<2<<endl;m=3;
}
if(m%2==0) m++;
for(i=m;i<=n;i+=2)
{
for(j=3;j<=i/j;j+=2)
if(i%j==0)
{j=0;break;}
if(j)
cout<<i<<endl;
}
cout<<endl;
}return 0;}

Resources