Project Euler 134
June 4, 2023
This is a simple problem, even when it has of difficult rating, even the code is short. There are no many concepts involved, just modular operations.
Statement
Consider the consecutive primes and . It can be verified that is the smallest number such that the last digits are formed by whilst also being divisible by .
In fact, with the exception of and , for every pair of consecutive primes , there exist values of for which the last digits are formed by and is divisible by . Let be the smallest of these values of .
Find for every pair of consecutive primes with .
Solution
Let's take a look to the number that ends with the digits of :
by the condition of the problem, this number should be divisible by :
since the problem requires to find the minimum number, must be the smallest positive value that satisfies the above equation.
The time complexity of this solution is , where the value of could be bounded by , so the time complexity is:
Code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define N 1000205
bitset <N> primes;
vector <pair<int, int> > p;
ll fastexp(ll x, ll y, ll p){
ll ans = 1;
while(y > 0){
if(y&1) ans = (ans*x)%p;
y >>= 1;
x = (x*x)%p;
}
return ans%p;
}
ll inv(ll x, ll p){
return fastexp(x, p-2, p);
}
void sieve(){
int prev = 10;
for(int i=2; i<N; i++){
if(!primes[i]){
if(i > prev) prev *= 10;
p.push_back({i, prev});
for(ll j=1LL*i*i; j<N; j+=i) primes[j] = 1;
}
}
}
int main(){
sieve();
ll ans = 0;
for(int i=2; i<p.size()-1; i++){
if(p[i].first > 1000000) break;
int p1 = p[i].first;
int p2 = p[i+1].first;
int n = (1LL*inv(p[i].second, p2)*(p2 - p1)) % p2;
if(n <= 0) n += p2;
ans += 1LL*n*p[i].second + p[i].first;
}
cout << ans << '\n';
return 0;
}
it runs on 20ms in my computer.