SPOJ - NDIV Cant find the error - primes

I have implemented sieve approach and it runs correctly for my test cases. I used a counter rather than a flag for all numbers and the times the numbers been accessed. When i run it on SPOJ it gives wrong answer.
Here is the link
http://www.spoj.com/problems/NDIV/
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
int main(){
vector<long int> vec;
long int sum=0,n,i,j,k,a,b,c;
double root;
cin>>a>>b>>n;
root = sqrt(b);
for(i=1;i<=b;i++) vec.push_back(1);
for(i=2;i<=root;i++){
k=i;
c=0;
for(j=2;j<=b && c<=b;j++){
c=k*j;
if(c<=b){
vec[c-1]++;
}
}
}
for(i=a;i<=b;i++){
if(sqrt(i)-floor(sqrt(i))!=0){
if(vec[i-1]*2 == n) {
sum++;
}
}
else {
if(vec[i-1]*2-1 == n) {
sum++;
}
}
}
cout<<sum;
}

Related

I am trying to find the factors of factorial of a number

I am trying to solve the SPOJ problem DIVFACT where we need to find the factorial of a number. Though I used the correct formulae and at the same time I also checked the special case of 0 and 1,still I am getting wrong answer and it's really difficult for me to figure out what's wrong with my code. Can someone please help me figure out the problem? For reference I am providing the link to the problem:- Link of the problem
#include<iostream>
#include<vector>
#define MOD 100000007
#define MAX 50001
#define pb push_back
using namespace std;
typedef long long ll;
ll no_of_factors(int num,vector<int> primes)
{
ll result=1;
for(int i=0;i<primes.size();i++)
{
if(primes[i]>num)
break;
ll k=primes[i];
ll count=0;
while(num/k!=0){
count=(count+(num/k))%MOD;
k=k*primes[i];
}
result=(result*((count+1)%MOD))%MOD;
}
return result;
}
vector<int> seive(){
bool isPrime[MAX];
vector<int> v;
for(int i=2;i<MAX;i++)
isPrime[i]=true;
for(int i=2;i*i<MAX;i++)
{
if(isPrime[i])
{
for(int j=i*i;j< MAX;j+=i)
isPrime[j]=false;
}
}
for(int i=2;i<MAX;i++)
{
if(isPrime[i])
v.pb(i);
}
return v;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int num;
ll divisors;
cin>>num;
vector<int> v1;
v1=seive();
divisors=no_of_factors(num,v1);
cout<<divisors<<endl;
}
return 0;
}
The problem states that the answer should be in MOD 10^9+7 but you have mistakenly defined MOD as 10^8+7.

SIGSEV SPOJ(PRIME1)

The problem I am solving is PRIME1 which says to print all the prime numbers between 2 numbers. Although the code I made runs properly on my compiler with the worst case as well, It gives me a SIGSEV error when compiling in SPOJ. Here is the code
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int t;
cin>>t;
while(t>0)
{
int a,b,n,p;
cin>>a>>b;
n = b-a;
bool prime[n+1];
memset(prime,true,sizeof(prime));
for(p=2;p*p<=b;p++)
{
if(prime[p]==true)
{
for(int i=p*2;i<=b;i+=p)
{
prime[i]=false;
}
}
}
(a==1)?p=2:p=a;
for(p;p<=b;p++)
if(prime[p])
cout<<p<<endl;
t--;
}
}

My C++ program for SPOJ generating primes gives expected output but crashes at the end. Please, let me know why it is happening

I know that the code is not an optimized one. I just wanted to practice segmented sieve of eratosthenes and finding prime numbers in a different way.
My compiler is Dev-C++ 5.11.
System specifications:
OS: Windows 8.1 Embedded Pro
Processor: Intel i5(3rd Generation)
RAM: 4Gb
I don't know if the problem is due to hardware compatibility, I haven't use any low level procedures though.
Please explain to me why the program crashes.
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#define NUM 1000000
using namespace std;
bool a[NUM]={0};
struct prime10
{
vector<long long int> primes;
int max;
prime10()
{
max=NUM;
}
}p;
void preprocess();
bool ifprime(unsigned long long int n);
void primemn(int m,int n);
int main()
{
preprocess();
int t=0;
scanf("%d",&t);
for(int i=0;i<t;i++)
{
int a,b;
scanf("%d %d",&a,&b);
primemn(a,b);
}
return 0;
}
void preprocess()
{
for (int i=2; i<=NUM; i++){
if (a[i]==0){
for (int j = i*2; j<=NUM; j+=i){
a[j]=1;
}
}
}
}
bool ifprime(unsigned long long int n)
{
if(n<NUM){
if(!a[n])
return true;
}
else if(n%2==0)
return false;
else
{
for(int i=3;i<sqrt((long double)n);i+=2)
{
if(ifprime(i))
{
if(n%i==0)
return false;
}
}
}
return true;
}
void primemn(int m,int n)
{
if(m<NUM&&n<NUM)
{
for(long long int i=m;i<=n;i++)
{
if(i==0||i==1)
{
}
else if(!a[i])
printf("%lld\n",i);
}
}
else if(m<NUM&&n>NUM)
{
if(n<=p.max)
{
for(long long int i=m;i<NUM;i++)
{
if(!a[i])
printf("%lld\n",i);
}
for(int i=0;i<p.primes.size();i++)
printf("%lld\n",p.primes[i]);
}
else if(n>p.max)
{
for(long long int i=m;i<NUM;i++)
{
if(!a[i])
printf("%lld\n",i);
}
for(int i=0;i<p.primes.size();i++)
printf("%lld\n",p.primes[i]);
for(int k=(p.max)+1;k<=n;k++)
if(ifprime(k)){
printf("%lld\n",k);
p.primes.push_back(k);
p.max=k;
sort(p.primes.begin(),p.primes.end());
}
}
}
else if(m>NUM&&n>NUM)
{
if(m<=p.max&&n<=p.max)
for(int o=0;o<p.primes.size();o++)
{
if(p.primes[o]>=m&&p.primes[o]<=n)
printf("%lld\n",o);
}
else if(m<=p.max&&n>p.max)
{
for(int o=0;o<p.primes.size();o++)
{
if(p.primes[o]>=m&&p.primes[o]<=n)
printf("%lld\n",o);
}
for(int o1=(p.max)+1;o1<=n;o1++)
if(ifprime(o1)){
printf("%lld\n",o1);
p.primes.push_back(o1);
p.max=o1;
sort(p.primes.begin(),p.primes.end());
}
}
else if(m>p.max&&n>p.max)
{
for(int o1=m;o1<=n;o1++)
if(ifprime(o1)){
printf("%lld\n",o1);
p.primes.push_back(o1);
p.max=o1;
sort(p.primes.begin(),p.primes.end());
}
}
}
}
You're writing outside the boundary of a - your preprocess loops should be < NUM.
Overstepping this boundary has undefined behaviour.
It may cause corruption of the neighbouring p, and as p's first member is a vector, a crash when the vector is destroyed is very likely.
Of course other scenarios are possible, but it sounds like this is what's happening in your case.

spoj prime conjecture PRIMEZUK

I am trying to solve the question http://www.spoj.com/problems/PRIMEZUK/
#include<iostream>
#include<cstdio>
#include<math.h>
#define l long long
using namespace std;
l chk(l a)
{
for(int i=2;i<=sqrt(a);++i)
{
if(a%i==0)
{
return a/i;
}
}
return 0;
}
main()
{
// freopen("in.txt","r",stdin);
int t,n,a;
l prod=1,flag;
//t=inp();
cin>>t;
for(int j=1;j<=t;++j)
{
cin>>n;
//n=inp();
if(n==0)
prod=-1;
else
prod=1;
while(n--)
{
cin>>a;
//a=inp();
prod*=a;
}
++prod;
flag=chk(prod);
if(!flag)
printf("Case #%d: %lld\n",j,prod);
else
printf("Case #%d: %lld\n",j,flag);
}
}
i am getting right answer for the sample test case but whne i submit i am getting wrong answer...any hints???
You are getting wrong answer because "return a/i" may also return a non-prime number.So you should check whether "return a/i" is prime or not..
Try This...
#include<bits/stdc++.h>
long long int check(long long int a)//Function to check whether a number is prime or not
{
long long int i,k;
k=sqrt(a);
for(i=2;i<=k;++i)
{
if(a%i==0) // if not prime
return check(a/i); //then find greatest prime
}
return a;
}
int main()
{
int j=1,t;
long long int n,a,prod,flag;
scanf("%d",&t);
while(t--)
{
scanf("%lld",&n);
if(n==0)
prod=-1;
else
prod=1;
while(n--)
{
scanf("%lld",&a);
prod*=a;
}
++prod;
printf("Case #%d: %lld\n",j,check(prod));
j++;
}
return 0;
}

finding the number of divisors don't know what is going wrong

I am coding to find the number of common divisors of two numbers n and k.
I am implementing it using the approach of finding the GCD g and then finding the number of divisors of the GCD.
However the code compiles but gives a not responding message on running :(
I have blown my head off on this.. can anyone please help in debugging..
Thanks in advance
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
vector<bool>p(1000002,true);
long int getgcd(long int a, long int b)
{ if(b == 0)
return a;
else
return getgcd(b, a % b);
}
void prime()
{ int i,j;
for(i=2;i<1000001;i++)
if(p[i])
for(j=i*i;j<1000001;j=j+i)
p[j]=false;
p[0]=false;
p[1]=false;
}
void divfind(long int a, long int b)
{
long int g;
g = getgcd(a,b);
int i,s,j=0,ans=1,num=0;
//short int fo[1000000];
s=(int) sqrt(g);
for(i=2;i<s+1;i++)
if(p[i])
{
while(g%i==0)
{g=g/i;
num++;
}
if(num)
ans*=++num;
num=0;
}
printf("%d\n",ans);
}
int main()
{
prime();
long int n;
int q;
scanf("%ld %d",&n,&q);
while(q--)
{
int t;
long int k;
scanf("%d%ld",&t,&k);
if(t==1)
divfind(n,k);
// else if(t==2)
// divi(n,k);
// else
// nodivi(n,k);
}
return 0;
}
You're running into integer overflows - i*i is only safe up to i=46340 (~2^15*sqrt(2)) with 32 bit integers, e.g:
i i*i
46339 2147302921
46340 2147395600
46341 -2147479015
46342 -2147386332
This leads to undefined behaviour.