PROBLEM LINK:
Setter: Shivansh Kaushal
Tester: Manan Grover
Editorialist: Ajit Sharma Kasturi
DIFFICULTY:
EASY
PREREQUISITES:
PROBLEM:
Chef needs to go from X to Y. For this he can consider the following two operations:
Suppose chef is at location C. Now he can
-
Go from C to C+1 in one step
-
Go from C to C+2 in one step if C+2 is prime.
We need to find the minimum number of steps to go from X to Y.
EXPLANATION:
-
If the move C to C+2 is possible, we must always prefer this rather than going from C \rightarrow C+1 \rightarrow C+2 because it always saves us one step.
-
Let us find the number of prime numbers P \leq Y for which P-2 \geq X. Let this value be tot.
-
Whenever we want to go to such P we will prefer the second operation, i.e going from P-2 to P directly using one step.
-
Therefore, our final answer will be Y-X-tot .
-
We can precompute the number of primes from 1 to N using the sieve method. From this information, we can easily calculate the number of primes in a range in O(1) time.
TIME COMPLEXITY:
O(N \log \log N) where N =10^7 for performing sieve.
SOLUTION:
Editorialist's solution
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e7;
bool prime[MAXN + 5];
int tot_primes_till[MAXN + 5];
void sieve()
{
int n = MAXN;
fill(begin(prime), end(prime), true);
prime[0] = prime[1] = false;
for (int i = 2; i <= n; i++)
{
tot_primes_till[i] = tot_primes_till[i - 1];
if (!prime[i])
continue;
tot_primes_till[i]++;
for (int j = 2 * i; j <= n; j += i)
{
prime[j] = false;
}
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
sieve();
int tests;
cin >> tests;
while (tests--)
{
int X, Y;
cin >> X >> Y;
int ans = Y - X - (tot_primes_till[Y] - tot_primes_till[X + 1]);
cout << ans << "\n";
}
}
Setter's solution
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll prime[10000004] = {0};
void sieve()
{
ll n=10000004;
prime[1]=1;
for(ll i=2;i<=n;i++)
{
for(int j=2;i*j<=n;j++)
{
prime[j*i]=1;
}
}
}
ll prime_in_range[10000004];
// Function to count primes in range.
void count_prime()
{
prime_in_range[0] = 0;
prime_in_range[1] = 0;
prime_in_range[2] = 1;
for(int i=3 ; i<=10000004 ; i++)
{
if(prime[i] == 0) // if the number if prime
{
prime_in_range[i] = prime_in_range[i-1] + 1;
}
else
{
prime_in_range[i] = prime_in_range[i-1];
}
}
}
int main()
{
// freopen("input2.txt","r",stdin);
// freopen("output2.txt","w",stdout);
ios::sync_with_stdio(false);
cin.tie(NULL);
ll t;
cin>>t;
sieve();
count_prime();
while(t--)
{
ll x,y;
cin>>x>>y;
cout << y - x - (prime_in_range[y]-prime_in_range[x+1])<<"\n";
}
}
Tester's solution
#include <bits/stdc++.h>
using namespace std;
#define N 10000001
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
vector<int> p(N);
for (int i = 2; i < N; i++)
{
p[i] = 1 - p[i];
if (p[i])
{
for (int j = 2 * i; j < N; j += i)
{
p[j] = 1;
}
}
p[i] += p[i - 1];
}
int t;
cin >> t;
while (t--)
{
int x, y;
cin >> x >> y;
cout << y - x - p[y] + p[x + 1] << "\n";
}
return 0;
}
Please comment below if you have any questions, alternate solutions, or suggestions.