Advertisement
kshuvo96

Project euler #134

Jun 19th, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.59 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. typedef unsigned long long ULL;
  3. using namespace std;
  4.  
  5. #define N 32000
  6. #define check(n, pos) (n & (1<<pos))
  7. #define on(n, pos) (n | (1<<pos))
  8. int status[N/64 + 2];
  9. vector<long long> primes, seg_primes;
  10. void sieve() {
  11.     int sqrtN = (int)sqrt((double)N) + 1;
  12.     for (int i = 3; i <= sqrtN; i += 2)
  13.         if ( check(status[i>>6], ((i>>1) & 31)) == 0)
  14.             for (int j = i*i; j <= N; j += 2*i)
  15.                 status[j>>6] = on(status[j>>6], ((j>>1) & 31));
  16.  
  17.     primes.push_back(2);
  18.     for (int i = 3; i <= N; i += 2)
  19.         if ( check(status[i>>6], ((i>>1) & 31)) == 0)
  20.             primes.push_back(i);
  21. }
  22. bool mark[1000000 + 100];
  23. void segment_sieve(ULL L, ULL R) {
  24.     for (ULL p : primes) {
  25.         if (p * p > R) break;
  26.         ULL base = (L/p) * p;
  27.         if (base < L) base += p;
  28.  
  29.         for (ULL j = base; j <= R; j += p)
  30.             mark[j - L] = true;
  31.         if (base == p) mark[base - L] = false;
  32.     }
  33.     if (L == 1) mark[0] = true;
  34. }
  35.  
  36. ULL next_prime(ULL p) {
  37.     bool f;
  38.     ULL i;
  39.     for (i = p + 2; i < 2 * p; i += 2) {
  40.         f = true;
  41.         for (ULL j = 2; j <= sqrt(i); ++j) {
  42.             if (i % j == 0) {
  43.                 f = false;
  44.                 break;
  45.             }
  46.         }
  47.         if(f) break;;
  48.     }
  49.     return i;
  50. }
  51.  
  52. long long egcd(long long a, long long b, long long& x, long long& y) {
  53.     if (b == 0) {
  54.         x = 1; y = 0;
  55.         return a;
  56.     }
  57.     long long x1, y1;
  58.     long long d = egcd(b, a%b, x1, y1);
  59.     x = y1;
  60.     y = x1 - (a/b)*y1;
  61.  
  62.     return d;
  63. }
  64.  
  65. long long linear_congruence(long long a, long long b, long long M) {
  66.     long long x, y;
  67.     long long d = egcd(a, M, x, y);
  68.     long long sol_x = x * (b/d);
  69.     sol_x = (sol_x%M + M) % M;
  70.     return sol_x;
  71. }
  72.  
  73. int main() {
  74.     sieve();
  75.     ULL S, L, R, len, T, p1, p2, c, a, M, x;
  76.     long long b; // ULL can't take -ve value.
  77.     cin >> T;
  78.     while (T--) {
  79.         cin >> L >> R;
  80.         memset(mark, false, sizeof(mark));
  81.         seg_primes.clear();
  82.         segment_sieve(L, R);
  83.         for (int i = 0; i <= (R-L); ++i) if(!mark[i]) seg_primes.push_back(L+i);
  84.  
  85.         len = seg_primes.size();
  86.         seg_primes.push_back(next_prime((ULL)seg_primes[len-1]));
  87.  
  88.         S = 0;
  89.         for (int i = 0; i < len; ++i) {
  90.             p1 = seg_primes[i]; p2 = seg_primes[i+1]; c = log10(p1) + 1;
  91.             a = round( pow(10, c) );
  92.             b = -p1;
  93.             M = p2;
  94.             x = linear_congruence(a, b, M);
  95.             S += (x * a + seg_primes[i]);
  96.         }
  97.         cout << S << "\n";
  98.     }
  99.     return 0;
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement