Segmented sieve of eratosthenes spoj Prime1 C++ - c++

I have been struggling with this problem http://www.spoj.com/problems/PRIME1/ and if anyone can help me finding the error in my code. I have used segmented sieve of eratosthenes and I have also looked through a lot of online resources but somehow I am getting a runtime error on spoj.
Thanks
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>
#include <map>
#include <cstdlib>
#include <cassert>
#define fora(i,a,b) for(i = a; i < b; i++)
#define fin(f) freopen(f, "r", stdin)
#define fout(f) freopen(f, "w", stdout)
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vll;
typedef vector<bool> vb;
const ll LIMIT = 1000000000;
void segmentedSieve(ll n, ll m, int segment_size) {
int i, j, s, p, range;
vb is_prime(range+1, true);
vb seg_primes(segment_size+1, true);
vi prime;
range = floor(sqrt((double)n));
fora (i, 2, range+1)
if (is_prime[i]) {
for (j = i*2; j <= range; j+=i)
is_prime[j] = false;
}
fora (i, 2, range+1)
if (is_prime[i] == 1)
prime.push_back(i);
fora (i, 0, prime.size()) {
p = prime[i];
s = m/p;
s *= p;
for (j = s; j <= n; j+=p) {
if (j < m) continue;
seg_primes[j-m] = false;
}
}
fora (i, 0, prime.size())
if (prime[i] >= m && prime[i] <= n) {
cout << prime[i] << endl;
}
fora (i, 0, n-m+1)
if (seg_primes[i] && (i+m) != 1) {
cout << i+m << endl;
}
}
int main()
{
int segment_size = 100000;
// fin("input.in");
int t;
cin >> t;
while (t--) {
ll a, b;
cin >> a >> b;
if (a > b)
segmentedSieve(a, b, segment_size);
else
segmentedSieve(b, a, segment_size);
if (t != 0)
cout << endl;
}
}

It seems range is uninitialized here:
void segmentedSieve(ll n, ll m, int segment_size) {
int i, j, s, p, range;
vb is_prime(range+1, true); // uninitialized range... !!
maybe you want
void segmentedSieve(ll n, ll m, int segment_size) {
int i, j, s, p, range;
range = floor(sqrt((double)n)); // This first...
vb is_prime(range+1, true); // then this
When possible you should initialize variables when you define them.
void segmentedSieve(ll n, ll m, int segment_size) {
int i, j, s, p; // no range here
int range = floor(sqrt((double)n)); // This first...
vb is_prime(range+1, true); // then this
In general you should postpone the definition of variables until you need them, i.e. don't define all variables in the start but do it as you need them.
p.s. As others have commented already - get rid of all that macro stuff...

Related

Time Complexity of two codes

What makes the first code faster than the second?
I tried those 2 codes one gave me a Time limit that exceeded 1000 ms and the other works on 140ms at a long test input of CodeForces test
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int n, m, a, l, r, c(0), d(0);
scanf("%d%d", &n, &m);
while (n--)
{
scanf("%d", &a);
if (a == 1)
{
c += 1;
}
else
{
d += 1;
}
}
int up = min(c, d) * 2;
while (m--)
{
scanf("%d%d", &l, &r);
printf((r - l) % 2 == 1 && r - l < up ? "1\n" : "0\n");
}
return 0;
}
the slow one is:
#include <bits/stdc++.h>
int main()
{
int n, ones{}, _ones{}, l, r, q, temp;
std::cin >> n >> q;
while(n--)
{
std::cin >> temp;
if(temp == 1)
ones++;
else
_ones++;
}
int common = std::min(ones, _ones) * 2;
while(q--)
{
std::cin >> l >> r;
std::cout << ((r - l) % 2 == 1 && r - l < common ? "1\n" : "0\n");
}
}
I'm not sure if library imports/includes are counted, but doing the #include <bits/stdc++.h> usually takes a lot of time generally
Might be because of that, maybe include only the ones you need

My program is exiting with return value 3221225620

I have written a cpp code for array rotation and the file handling part is a bit tricky for me.
The code itself is correct but even though the files are in the same directory as the code it is not working for some reason
#include <math.h>
#include <algorithm>
#include <bits/stdc++.h>
#include <iostream>
#include <fstream>
using namespace std;
int ar[100];
// #define crap ios_base::sync_with_stdio(false);cin.tie(NULL);
int gcd(int a, int b)
{
if (b == 0)
return a;
else
return gcd(b, a % b);
}
void leftRotate(int arr[], int d, int n)
{
d = d % n;
int g_c_d = gcd(d, n);
for (int i = 0; i < g_c_d; i++) {
int temp = arr[i];
int j = i;
while (1) {
int k = j + d;
if (k >= n)
k = k - n;
if (k == i)
break;
arr[j] = arr[k];
j = k;
}
arr[j] = temp;
}
}
//int *func(int m)
//{
// int *p;
// p=new int[m];
// return (p);
//}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
// crap;
int n,d;
cin>>n>>d;
// ar=func(n);
// cout<<sizeof(ar);
for (int i=0;i<n;i++)
{
cin>>ar[i];
}
leftRotate(ar, d, n);
for (int i = 0; i < n; i++)
cout << ar[i] << " ";
return 0;
}
The code itself is working and returning correct output in the terminal but I cant seem to find the issue here
I have tried without file handling and it was giving a return value 3221225620 at the terminal
sample input is:
5 2
1 2 3 4 5
here shows a possible error:
3221225620 (0xC0000094): Zero Division Error
means that a divisor in your code could sometime be zero.
as for your code(line 20: d = d % n;), when your n is 0, the output will show return value 3221225620
so please check your data in "input.txt"

Is there any efficient way to get longest possible sorted array from alternate elements of two arrays?

For Example:
N=5, M=4
A=[4,2,10,5,9]
B=[4,5,6,15]
so the one of longest sorted array is [2,4,5,6,9,15]
this is my Approach but want to know is there any efficient approach available. I can assure it is not from any online coding contest, it is being asked to me in an interview so I want to know the efficient approach if any.
#include<bits/stdc++.h>
using namespace std;
int mx=0;
void generateUtil(int A[], int B[], int C[], int i, int j, int m, int n,
int len, bool flag)
{
if (flag)
{
if (len)
mx=max(mx,len+1);
for (int k = i; k < m; k++)
{
if (!len)
{
C[len] = A[k];
generateUtil(A, B, C, k+1, j, m, n, len, !flag);
}
{
if (A[k] > C[len])
{
C[len+1] = A[k];
generateUtil(A, B, C, k+1, j, m, n, len+1, !flag);
}
}
}
}
{
for (int l = j; l < n; l++)
{
if (B[l] > C[len])
{
C[len+1] = B[l];
generateUtil(A, B, C, i, l+1, m, n, len+1, !flag);
}
}
}
}
void generate(int A[], int B[], int m, int n)
{
int C[m+n];
generateUtil(A, B, C, 0, 0, m, n, 0, true);
}
int main()
{
int n,m,i,j;
cin>>n>>m;
int A[n],B[m];
for(i=0;i<n;i++)
{
cin>>A[i];
}
for(j=0;j<n;j++)
{
cin>>B[j];
}
generate(A, B, n, m);
cout<<mx<<"\n";
return 0;
}
Depends on what you mean by efficient. This is pretty efficient if we're measuring e.g. code length, ease of understanding, and chance of bugs:
#include <algorithm>
#include <iterator>
#include <set>
std::set<int> result;
std::copy(std::begin(A), std::end(A), std::inserter(result, result.end()));
std::copy(std::begin(B), std::end(B), std::inserter(result, result.end()));
for (int e : result) { std::cout << e << ' '; }
Also: Why should I not #include <bits/stdc++.h>?.
Edit: It seems this doesn't actually do what is asked. Although at this point I have no clue what is being asked.
The following uses the standard algorithms library. As to whether that is what your employer wants is an open question!
#include <algorithm>
#include <iostream>
#include <iterator>
int main()
{
int A[] = {4,2,10,5,9};
int B[] = {4,5,6,15};
std::sort(std::begin(A), std::end(A));
std::sort(std::begin(B), std::end(B));
int C [std::size(A) + std::size(B)];
std::merge(std::begin(A), std::end(A),std::begin(B), std::end(B),C);
// std::unique will return one after last valid element
auto iter = std::unique(std::begin(C), std::end(C));
for ( auto p = std::begin(C); p != iter; ++p){
std::cout << *p << ",\n";
}
}

Non-Divisible Subset - Hackerrank

I am trying to solve the Non-Divisible Subset problem from Hackerrank (https://www.hackerrank.com/challenges/non-divisible-subset). I am trying to use the idea that if the sum of a and b is divisible by k, then a%k+b%k = k, however, it's not working very well.
Here is what I've written so far:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
int k;
cin >> n;
cin >> k;
int j;
vector<int>numbers;
vector<int>remainders;
for(int i = 0; i < n; i++) {
int z;
cin >> z;
numbers.push_back(z);
}
for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); it++) {
j = *it % k;
remainders.push_back(j);
}
for(vector<int>::iterator it2 = remainders.begin(); it2 != remainders.end(); it2++) {
int remainderCount = 0;
int otherRemainderCount = 0;
otherRemainderCount = std::count(remainders.begin(), remainders.end(), k-*it2);
remainderCount = std::count(remainders.begin(), remainders.end(), *it2);
if (remainderCount > otherRemainderCount) {
theChosenOne = *it2;
} else if (otherRemainderCount > remainderCount) {
theChosenOne = k-*it2;
}
cout << theChosenOne << endl;
}
return 0;
}
I created a vector for the remainders and I am using the std::cout function to find out which remainder appears more in the vector. If K would be 5, *it2 = 4, and k-*it2 = 1. If *it2 appears more times, then I would choose *it2. Otherwise, I would choose k-*it2.
Your solution looks to be on the right track, but there is some change that is needed.
You basically need to hash the numbers in the array to proper location.
Have an array rem[k] initialised to 0.
Iterate over the n numbers in the array, and do the following:
rem[array[i]%k]++;
Now you have to deal with only the rem[] array, to find the maximum subset. The rem array has size of maximum k<=100. Make use of the small size of rem[] array to find the solution efficiently.
Edit: Adding the code for you.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n,i,k;
cin>>n>>k;
int arr[n];
int rem[k]={0};
for(i=0;i<n;i++)
{
cin>>arr[i];
}
for(i=0;i<n;i++)
{
rem[arr[i]%k]++;
}
int count = 0;
for(i=1;i<=k/2;i++)
{
count = count + max(rem[i],rem[k-i]);
}
count = count + (rem[0]>0?1:0);
if(k%2==0)
{
count = count - rem[k/2];
if(rem[k/2]>0)
count = count + 1;
}
cout<<count;
return 0;
}
After you have found out the contents of the rem[] array, its time to find the maximum subset. If you select rem[1] then you cannot select rem[k-1] as any two numbers, one from rem[1] and another from rem[k-1] can be summed together which will be divisible by k that we don't want. So we find whichever is maximum out of rem[i] and rem[k-i] and add it to the count
My code uses the above logic..
Hope it helps!!!
int main() {
int n,k;
cin>>n>>k;
vector <int> a(n);
vector <int> r(k,0);
for(int i=0;i<n;i++)
{
cin>>a[i];
r[a[i]%k]++;
}
int ctr=min(1,r[0]);
for(int a=1;a<(k/2+1);a++)
{
if(a!=k-a)
ctr+=max(r[a],r[k-a]);
}
if(k%2==0&&r[k/2]!=0)
ctr++;
cout<<ctr;
return 0;
}
This seemed to work
#include <stdio.h>
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
int main() {
int n, k, a, total = 0;
scanf("%d %d", &n, &k);
int mods[k];
for (int i = 0; i < k; i++)
mods[i] = 0;
while (n--) {
scanf("%d", &a);
mods[a % k]++;
}
// can only have 1 value congruent to 0 mod k
total += min(1, mods[0]);
// if even, can only have 1 value congruent to k/2 mod k
if (k % 2 == 0)
total += min(1, mods[k / 2]);
// for all others, pick max of those k and n-k mod k
for (int d = 1; d < (k + 1) / 2; d++) { // for all others,
total += max(mods[d], mods[k - d]);
}
printf("%d", total);
return 0;
}

Can't understand why my program throws error

My code is in
#include <iostream>
#include <string>
#include <algorithm>
#include <climits>
#include <vector>
#include <cmath>
using namespace std;
struct State {
int v;
const State *rest;
void dump() const {
if(rest) {
cout << ' ' << v;
rest->dump();
} else {
cout << endl;
}
}
State() : v(0), rest(0) {}
State(int _v, const State &_rest) : v(_v), rest(&_rest) {}
};
void ss(int *ip, int *end, int target, const State &state) {
if(target < 0) return; // assuming we don't allow any negatives
if(ip==end && target==0) {
state.dump();
return;
}
if(ip==end)
return;
{ // without the first one
ss(ip+1, end, target, state);
}
{ // with the first one
int first = *ip;
ss(ip+1, end, target-first, State(first, state));
}
}
vector<int> get_primes(int N) {
int size = floor(0.5 * (N - 3)) + 1;
vector<int> primes;
primes.push_back(2);
vector<bool> is_prime(size, true);
for(long i = 0; i < size; ++i) {
if(is_prime[i]) {
int p = (i << 1) + 3;
primes.push_back(p);
// sieving from p^2, whose index is 2i^2 + 6i + 3
for (long j = ((i * i) << 1) + 6 * i + 3; j < size; j += p) {
is_prime[j] = false;
}
}
}
}
int main() {
int N;
cin >> N;
vector<int> primes = get_primes(N);
int a[primes.size()];
for (int i = 0; i < primes.size(); ++i) {
a[i] = primes[i];
}
int * start = &a[0];
int * end = start + sizeof(a) / sizeof(a[0]);
ss(start, end, N, State());
}
It takes one input N (int), and gets the vector of all prime numbers smaller than N.
Then, it finds the number of unique sets from the vector that adds up to N.
The get_primes(N) works, but the other one doesn't.
I borrowed the other code from
How to find all matching numbers, that sums to 'N' in a given array
Please help me.. I just want the number of unique sets.
You've forgotten to return primes; at the end of your get_primes() function.
I'm guessing the problem is:
vector<int> get_primes(int N) {
// ...
return primes; // missing this line
}
As-is, you're just writing some junk here:
vector<int> primes = get_primes(N);
it's undefined behavior - which in this case manifests itself as crashing.