Can I optimize segmented Sieve of Eratosthenes - c++

I am trying to find the number of primes in a given range in c++. But it still shows TLE. Can I optimize it further?
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
std::cin>>T;
while(T--){
int r,Y;
cin >> r>>Y;
int count=0;
int l=1;
vector<bool>isPrime(r - l + 1,true); //filled by true
for (long long i = 2; i * i <= r; ++i) {
for (long long j = max(i * i, (l + (i - 1)) / i * i); j <= r; j += i) {
if(isPrime[j - l]){
isPrime[j - l] = false;
count++;
}
}
}
count=isPrime.size()-count-1;
std::cout<<count<<"\n";
}
return 0;
}

Related

C++ - Count all possible scalene triangle with length of each side smaller than N

With 3 <= N <= 100000, I tried the following O(n^2) algo but I want it to be efficient, O(n)
please help with homework :D
typedef long long ll;
int n;
int solve(int n)
{
int ans=0;
for(int i = n; i >= 3; i--)
{
int j = 1, k = i -1;
while(j < k)
{
if(j + k > i)
{
ans += k - j;
k--;
}
else
j++;
}
}
return ans;
}

Euler's totient function practice code fails in online judge

This is specifically UVA problem number 11327:
Given a series of all rational numbers between 0 and 1 (0/1, 1/1, 1/2, 1/3, 2/3,..., n/d) print the k-th fraction
I've used their debugger and my program outputs the exact same answers they give but the judge still marks it as incorrect.
I'm using Euler's totient function to find the denominator and iterating through GCDs that equal 1 to find the numerator. As far as I could find online, this should suffice.
Any help would be appreciated.
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <math.h>
using namespace std;
//Calculate the greatest common divisor of a and b
long long GCD(long long a, long long b){
if (a == 0){
return b;
}
return GCD(b%a, a);
}
int main(){
long long input;
vector <long long> inputVector;
vector <long long> phiValues;
long long totient;
long long total;
int numerator;
int denominator;
while(cin >> input){
if(input == 0){
break;
}
inputVector.push_back(input);
}
// Calculate phi for all integers from 1 to
// 20000 and store them
for(int i = 1; i <= 200000; i++){
long long current = i;
totient = current;
for(long long k = 2; k <= sqrt(i); k++){
if(current % k == 0){
totient -= totient / k;
while(current % k == 0){
current /= k;
}
}
}
if(current > 1){
totient -= totient / current;
}
phiValues.push_back(totient);
}
for(int i = 0; i < inputVector.size(); i++){
long long N = inputVector[i];
total = 1;
for(int j = 0; j <= phiValues.size(); j++){
if(total >= N){
if(N == 1){ //For the case of N = 1
denominator = 1;
}else{
denominator = j;
}
total -= phiValues[j-1];
break;
}
total += phiValues[j];
}
int index = 0;
for(int j = 1; j <= denominator; j++){
if(GCD(j, denominator) == 1){
index++;
if(index == N - total){
numerator = j;
break;
}
}
}
cout << numerator << '/' << denominator << endl;
}
return 0;
}
Here #jte states that calculation of PHI can be achieved in O(N*logN):
phi[0] = phi[1] = 0;
for (int i=2; i<maxn; ++i)
phi[i] = i - 1;
for (int i=1; i<maxn; ++i)
for (int j=i+i; j<maxn; j+=i)
phi[j] -= phi[i];
I could not find problem of your code. May be it is TLE (time limit exceeded) problem, because you should use binary search to find denominator. But this code will get ACCEPTED:
#include<bits/stdc++.h>
using namespace std;
const int N = 200031;
int pr[N+31],phi[N+31];
vector<int> P[N+31];
long long S[N+31];
int count(int n,int X)
{
int res=n;
int N=P[X].size();
for (int mask=1;mask<(1<<N);mask++) {
int C=0;
int prod=1;
for (int j=0;j<N;j++)
if (mask&(1<<j))
C++,
prod*=P[X][j];
if (C%2)
res-=n/prod;
else
res+=n/prod;
}
return res;
}
int solve(int need,int val)
{
int l,r;
l=1;
r=val;
while (l<r) {
int mid=l+r;
mid/=2;
int Q=count(mid,val);
if (Q>=need)
r=mid;
else
l=mid+1;
}
return l;
}
int main()
{
ios_base::sync_with_stdio(0);
pr[1]=1;
for (int i=1;i<=N;i++) {
if (pr[i])
continue;
for (int j=i;j<=N;j+=i)
P[j].push_back(i),
pr[j]=1;
}
for (int i=1;i<=N;i++) {
phi[i]=i;
for (int j=0;j<P[i].size();j++) {
int val=P[i][j];
phi[i]=phi[i]/val*(val-1);
}
}
for (int i=1;i<=N;i++)
S[i]=S[i-1]+phi[i];
long long x;
while (cin>>x) {
if (x==0)
break;
--x;
if (x==0)
{
cout<<0<<"/"<<1<<endl;
continue;
}
int id=lower_bound(S+1,S+N+1,x)-S;
x-=S[id-1];
int ps=solve(x,id);
cout<<ps<<"/"<<id<<endl;
}
return 0;
}

how to Calculate this series

#include <iostream>
#include <math.h>
using namespace std;
int fact(int number)
{
unsigned long long int p = 1;
if (number == 0) {
return p;
}
for (int i = 1; number >= i; i++) {
p = p * i;
}
return p;
}
int main()
{
long long int a, x, sum = 0, result;
int n ;
cin >> a;
cin >> x;
cin >> n;
for (int k = 0; n >= k; k++) {
result = fact(n) / (fact(k) * fact(n - k));
sum = sum + (result * pow(x, k) * pow(a, n - k));
}
cout << sum;
return 0;
}
I want to calculate this series
So I considered the long long int sum, but the sum number sometimes gets too big. What can I do to save the sum number without using library?
First of all I would suggest to use binomial theorem -- what you are computing is just pow(x+a, n)
If you want to do this through series, do not compute the binomial coefficient using factorials but something like this
int bin_coeff(int n, int k){
int lim = k > n/2 ? k : n - k;
int sum = 1;
for (int i = n; i > lim; i--){
sum *= i;
}
for (int i = 2; i < (n - lim + 1); i++){
sum /= i;
}
return sum;
}

LAP algorithm not working with large numbers

include
#include <fstream>
#include <algorithm>
using namespace std;
long int lenghtOfLongestAP(long int set[],long int n)
{
if (n <= 2) return n;
long int L[n][n];
long int llap = 2;
for (long int i = 0; i < n; i++)
L[i][n-1] = 2;
for (long int j=n-2; j>=1; j--)
{
int i = j-1, k = j+1;
while (i >= 0 && k <= n-1)
{
if (set[i] + set[k] < 2*set[j])
k++;
else if (set[i] + set[k] > 2*set[j])
{ L[i][j] = 2, i--; }
else
{
L[i][j] = L[j][k] + 1;
llap = max(llap, L[i][j]);
i--; k++;
}
}
while (i >= 0)
{
L[i][j] = 2;
i--;
}
}
return llap;
}
int main()
{
ofstream cout("Output.txt");
ifstream cin("cablecar-sub4-attempt3.txt");
int ab;
cin >> ab;
for (long int z = 0; z < ab; z++)
{
long int bs;
cin >> bs;
long int array[bs];
for(long int h = 0; h<bs; h++)
cin >> array[h];
sort(array, array + bs);
cout << "Case #" << z+1 << ": " << lenghtOfLongestAP(array, bs) << endl;
}
return 0;
}
This is my code. It is a LAP (Largest arithmetic progression) algorithm, so it finds the largest progression in an sorted array. I have the following set of data:
pastebin.com/77meKfKW
Strangely, the program crashes after case 30, which it shouldn't. What kind of problem might it be and how can I fix it?
This is probably a stack overflow. You are allocating your array on the stack with 267*267 entries which uses a lot of memory.
Try allocating the memory on the heap instead, or simply changing the array from being local to being global (with a fixed maximum value of n).
e.g.
change
long int lenghtOfLongestAP(long int set[],long int n)
{
if (n <= 2) return n;
long int L[n][n];
to
long int L[1000][1000]; // or whatever your maximum n might be
long int lenghtOfLongestAP(long int set[],long int n)
{
if (n <= 2) return n;

Project Euler 16 2^1000 i got 1319?

i checked the answer and it's not off by much from my answer, but it is still an error. can someone check my coding to see what mistake caused me to get a value of 1319?
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int k = 0;
int o = 0;
vector<int> n(1,0);
n[0] = 1;
while (k < 1001)
{
for (int l = 0; l < n.size(); l++)
n[l] = n[l] * 2;
for (int l = 0; l < n.size(); l++)
{
if (n[l] >= 1000000)
{
int m;
if (l == n.size() - 1)
n.resize(n.size() + 1);
m = n[l] / 1000000;
n[l] = n[l] % 1000000;
n[l+1] = n[l+1] + m;
}
}
k++;
}
for (int l = 0; l < n.size(); l++)
o = o + int (n[l]/1000000) + int ((n[l] % 1000000) / 100000) + int ((n[l] % 100000) / 10000) + int ((n[l] % 10000) / 1000) + int ((n[l] % 1000) / 100) + int ((n[l] % 100) / 10) + n[l] % 10;
cout << o;
cin >> k;
return 0;
}
Make it
while (k < 1000)
in the outer loop condition.
In the while loop, you start with a representation of 2^k in the vector with the value k has at entering the loop. So you are actually computing 2^1001 and not 2^1000.
Problem of solving this in c++ is datatype limit, "int" is not sufficient to calculate 2^1000.
I have solved a prototype for this i.e. sum of the digits of number 2^4.The power 2^4 is 16 and sum of digits id 7.
Hope the code guides u.
#include<iostream.h>
#include<conio.h>
void main()
{
int count=1;
int power=1;
int sum=0;
while(count<=4)
{ count++;
power=power*2;
}
cout<<"The power is"<<power<<"\t";
while(power!=0)
{
int digit=power%10;
sum=sum+digit;
power=power/10;
}
cout<<"The sum of digits is"<<sum;
getch();
}