run time error (SIGSEGV) SPOJ Sieve of Eratosthenes [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Hi I'm getting SIGSEGV error for this problem, dont know where is th problem: http://www.spoj.com/problems/PRIME1/
I tried to solve it by sieve-of-Eratosthenes algo given on Wikipedia.
here is my code, please help thanks in advance.
int main()
{
int t; // test cases
cin>>t;
while(t--)
{
long int m,n;
cin>>m>>n;
if( 1 <= m <= n <= 1000000000 && n-m<=100000)
{
bool a[n];
for(long int i=2;i<=n;i++)
{
a[i]=true; // set all to true
}
a[0]=false;
a[1]=false;
for( long int i=2;i*i<=n;i++)
{
if(a[i])
{
for( long int k=i*i;k<=n;k+=i)
{
a[k]=false;
}
}
}
for(long int i=m;i<=n;i++)
{
if(a[i])
cout<<i<<endl; //Now all i such that a[i] is true are prime.
}
cout<<endl;
}
else
return -1;
}
return 0;
}

You have to use gdb to find out exactly what happened. There are many things wrong with this code.
As pointed out in the comments, for n large enough your a[n] will overflow the stack.
You have an off-by-one error in your first and third for loops; you check a[n] but only allocated up to a[n-1]. All of the i <= n should be i < n
if( 1 <= m <= n <= 1000000000 && n-m<=100000) is probably not what you intended; for any positive integer 'n', (1 <= m <=n) will be true

There are 3401 primes below the square root of 109. That's all you need to sieve any segment of numbers below the 109 upper limit.
So, first, sieve a segment from 2 to 31622. Store the resulting 3401 prime integers in an array.
Then for each pair of numbers m <= n, m >= n - 100000 create a temporary array covering the segment from m to n inclusive, and sieve it with those primes you've calculated in the first step. You can stop each sieving when a prime's square is above a given n:
for( i=0; primes[i]*primes[i] <= n; ++i)
{
....
See also my posts about the "offset sieve" of Eratosthenes.

This problem has been treated before on SO. For example, see Sieve of Eratosthenes on Stack Overflow. You may also want to read this blog that describes a typical C implementation: C implementation of Sieve of Eratosthenes. As pointed out above there are multiple issues with your code, so many in fact that you need to think about reorganizing it completely. Please read the linked posts to get ideas for how to do that successfully.

Related

How to find the power of the array elements? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I need to check if A[0] ^ A[1] ^ A[2] ... ^ A[N] is even or odd.
Is this code right??
#include <bits/stdc++.h>
#include <cmath>
using namespace std;
int main(){
long long n;
cin >> n;
int a[n];
long int mp;
for(int i = 0; i < n; i++){
cin >> a[i];
mp = pow(a[i], a[i+1]);
}
if (mp % 2 == 0){
cout << "YES";
}
else cout<<"NO";
}
Do the maths first.
Consider that
odd * odd * odd * odd .... * odd == odd
You can multiply any odd factors and the result is always odd. Whether a number is odd or even is equivalent to: It has a prime factor 2. Some integer raised to some other integer cannot remove a prime factor, it can also not add a prime factor when it wasn't present before. You start with some x and then
x * x * x * x * x .... * x = y
has the same prime factors as x, just with different powers. The only exceptions is to get an odd number from an even one when you raise a number to power 0, because x^0 = 1.
Ergo, you are on the wrong track. Instead of brute force raising numbers to some power you merely need to consider ...
is A[0] odd or even
is any of the other elements 0 (remember that (a^b)^c) is just a^(b*c))
Thats it.
I will not write the code for you to not spoil the exercise. But I should tell you whats wrong with your code: pow is not made to be used with integers. There are many Q&As here about pow returning a "wrong" result, which is most often just due to wrong expectations. Here is one of them: Why does pow(n,2) return 24 when n=5, with my compiler and OS?. Moreover, you are accessing the array out of bounds in the last iteration of the loop. Hence all your code has undefined behavior. Output could be "maybe" or something else entirely. Also, your code merely calculates a[i] ^ a[i+1] and after the loop you only consider the very last result. Thats not what the task you describe asks for. Last but not least, Why aren't variable-length arrays part of the C++ standard?. Use std::vector for dynamically sized arrays.

Find how many numbers that are perfect squares and the sqrt() is a prime number in a L, R range

First off all, feel free to improve the formatting of the question
This question is already solved by Goswin von Brederlow!
Hello, i'm praticing programming and this problem came across and i don't know how is the best way to solve this:
The question have T test cases that consists in:
Given a range L and R, find how many numbers meet the constraints:
i) Number is a perfect square;
ii) The sqrt(Number) is a prime number.
Limits:
1 <= T <= 1e4
1 <= L, R <= 1e12
Time limit: 1 second
So, i tried it with a simple idea of pre-processing with an unodered_map(lld, bool) all the answers with the sieve of eratosthenes for each sqrt(Number) given that Number is a perfect square
After, I pass in range pow(sqrt(l), 2) and increments it the next odd number... like: 4 9 16 25, the difference are odd numbers: 5 7 9...
My code:
long long int l, r; scanf("%lld %lld", &l, &r);
long long int odd = ceil(sqrt(l)), n = odd*odd;
odd = (2*odd) + 1;
long long int ans = 0;
while((n >= l && n <= r)){
it = h.find(n);
ans = ans + it->second;
n = n + odd;
odd = odd + 2;
}
But a i still got TLE, i need some help guys, thank you!
The only question I see I infer from "i don't know how is the best way to solve this".
Your way seems to be pretty smart already. You have some bugs even in just the bit of code you pasted. You seem to compute the sum of the numbers instead of counting them.
One thing I could think of improving is the counting itself. Looks like you have a hash table of all the squares of primes and you simply test all auqares if they are in the table.
Why not make a balanced tree out of the primes? In each node you store the minimum and maximum number and the count for the subtree. The leaves would be (n, n, 1) where n is one of the squares of primes. Given L and R you can then go through the tree and sum up all subtrees that are in the interval and recurse into subtrees that are only partially inside. Ignore everything outside. That should add a logarithmic factor to your complexity.

How is this code working for finding the number of divisors of a number?

http://www.spoj.com/problems/NDIV/
This is the problem statement. Since i'm new to programming, this particular problem ripped me off, I found this particular code on the internet which when I tried submitting got AC. I want to know how this code worked, as I have submitted it from online source which itself is bad idea for beginners.
#include <bits/stdc++.h>
using namespace std;
int check[32000];
int prime[10000];
void shieve()
{
for(int i=3;i<=180;i+=2)
{
if(!check[i])
{
for(int j=i*i;j<=32000;j+=i)
check[j]=1;
}
}
prime[0] = 2;
int j=1;
for(int i=3;i<=32000;i+=2)
{
if(!check[i]){
prime[j++]=i;
}
}
}
int main()
{
shieve();
int a,b,n,temp,total=1,res=0;
scanf("%d%d%d",&a,&b,&n);
int count=0,i,j,k;
for(i=a;i<=b;i++)
{
temp=i;
total=1;
k=0;
for(j=prime[k];j*j<=temp;j=prime[++k])
{
count=0;
while(temp%j==0)
{
count++;
temp/=j;
}
total *=count+1;
}
if(temp!=1)
total*=2;
if(total==n)
res++;
}
printf("%d\n",res);
return 0;
}
It looks like the code works on the sieve of eratosthenes, but a few things i'm unable to understand.
Why the limit of array "check" is 32000?
Again why the limit for array prime is 10000?
Inside main, whatever is happening inside the for loop of j.
Too many confusions regarding this approach, can someone explain the whole algorithm how it's working.
The hard limit on the arrays is set probably because the problem demands so? If not then just bad code.
Inside the inner loop, you are calculating the largest power of a prime that divides the number. Why? See point 3.
The number of factors of a number n can be calculated as follows:
Let n = (p1)^(n1) * (p2)^(n2) ... where p1, p2 are primes and n1, n2 ... are their exponents. Then the number of factors of n = (n1 + 1)*(n2 + 1)...
Hence the line total *= count + 1 which is basically total = total * (count + 1) (where count is the largest exponent of the prime number that divides the original number) calculates the number of prime factors of the number.
And yes, the code implements sieve of Eratosthenes for storing primes in a table.
(Edit Just saw the problem - you need at least 10^4 boolean values to store the primes (you don't actually need to store the values, just a flag indicating whether the values are prime or not). The condition given is 0 <= b - a <= 10^4 , So start your loop from a to b and check for the bool values stored in the array to know if they are prime or not.)

Problems with program which find prime number from 1 to 100

I wrote this program which find and displays prime numbers from 1 to 100
int ifprime (int n)
{
int i=1;
while (i<= n)
{
i++;
if (n%i == 0)
{
return false;
break;
}
else continue;
}
return true;
}
int prime_numbers (void)
{
bool result;
for (int i = 2; i<=100; ++i)
{
result = ifprime(i);
if (result==true) cout<<i<<endl;
else continue;
}
}
int main()
{
prime_numbers();
return 0;
}
The program displays nothing. Why?
Change your loop to:
for(int i=2; i<n; i++){
if(n%i==0){
return false;
}
}
Or your while end condition to:
while(i < n-1)
As pointed out in the comments, every non-zero number is divisible by 1 and itself. Change this line (line 4)
while (i<= n)
to
while (i< n)
If that's your whole code, then you're simply missing a main() function.
Though it shouldn't link without a main() function.
There are some additional problems with your code, but that's probably the reason why you don't see any output.
Try adding this to your file:
int main()
{
prime_numbers();
return 0;
}
Many people have pointed out the problem with:
while (i <= n)
...because you allow i to be n in your for loop, every natural number is divisible by itself so it wrongly accuses prime numbers of being composites. As people pointed out, the quick fix is:
while (i < n)
But the reason why I reply is because there are other things you can do to make your code better. The first improvement is that you don't need to try dividing by numbers greater than the square root of n because if there is a greater than it, then there is also a divisor less than it. So you could do something like this:
while (i*i <= n)
But there are further improvements you can do on that. For example, why should you have to compute i*i every iteration? If you pre-compute square root of n (rounded to int), then you can avoid that computation.
Another optimization is that you can avoid trial dividing by half of the numbers: if n is not divisible by 2, then no reason to try any other even numbers. So you can jump i by 2 every time in your inner loop. There are other tricks if you want to eliminate trial dividing by numbers divisible by 3.
Really, however, there is a nice super-duper fast algorithm to find the first x primes if you don't mind using order x bytes of memory. It is called the sieve of Eratosthenes, and it is really fun to implement. Once you get your current code optimized, I recommend trying the sieve.
The problem of finding prime numbers efficiently has received an enormous amount of attention in the academic literature, and it is now considered solved. But it takes a lot of study to learn it.

C++ sieve of Eratosthenes with array [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'd like to code the famous Sieve of Eratosthenes in C++ using just array as it would be a set where I can delete some elements on the way to find out primes numbers.
I don't want to use STL (vector, set)... Just array! How can I realize it?
I try to explain why I don't want to use STL set operator: I'm learning C++ from the very beginning and I think STL is of course useful for programmers but built on standard library, so I'd like to use former operators and commands. I know that everything could be easier with STL.
The key to the sieve of Eratosthenes's efficiency is that it does not, repeat not, delete ⁄ remove ⁄ throw away ⁄ etc. the composites as it enumerates them, but instead just marks them as such.
Keeping all the numbers preserves our ability to use a number's value as its address in this array and thus directly address it: array[n]. This is what makes the sieve's enumeration and marking off of each prime's multiples efficient, when implemented on modern random-access memory computers (just as with the integer sorting algorithms).
To make that array simulate a set, we give each entry two possible values, flags: on and off, prime or composite, 1 or 0. Yes, we actually only need one bit, not byte, to represent each number in the sieve array, provided we do not remove any of them while working on it.
And btw, vector<bool> is automatically packed, representing bools by bits. Very convenient.
From Algorithms and Data Structures
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
void runEratosthenesSieve(int upperBound) {
int upperBoundSquareRoot = (int)sqrt((double)upperBound);
bool *isComposite = new bool[upperBound + 1];
memset(isComposite, 0, sizeof(bool) * (upperBound + 1));
for (int m = 2; m <= upperBoundSquareRoot; m++) {
if (!isComposite[m]) {
cout << m << " ";
for (int k = m * m; k <= upperBound; k += m)
isComposite[k] = true;
}
}
for (int m = upperBoundSquareRoot; m <= upperBound; m++)
if (!isComposite[m])
cout << m << " ";
delete [] isComposite;
}
int main()
{
runEratosthenesSieve(1000);
}
You don't want to use STL, but that's not a good idea
STL makes life much simpler.
Still consider this implementation using std::map
int max = 100;
S sieve;
for(int it=2;it < max;++it)
sieve.insert(it);
for(S::iterator it = sieve.begin();it != sieve.end();++it)
{
int prime = *it;
S::iterator x = it;
++x;
while(x != sieve.end())
if (((*x) % prime) == 0)
sieve.erase(x++);
else
++x;
}
for(S::iterator it = sieve.begin();it != sieve.end();++it)
std::cout<<*it<<std::endl;