// Basic Sieve - generates primes up to Nvector<bool> sieve(int N) { vector<bool> prime(N + 1, true); prime[0] = prime[1] = false; for (int i = 2; i * i <= N; i++) if (prime[i]) for (int j = i * i; j <= N; j += i) prime[j] = false; return prime;}// Modified Sieve - stores smallest prime factorvector<int> spf(int N) { vector<int> spf(N + 1); for (int i = 2; i <= N; i++) spf[i] = i; for (int i = 2; i * i <= N; i++) if (spf[i] == i) for (int j = i * i; j <= N; j += i) if (spf[j] == j) spf[j] = i; return spf;}// Prime factorization using SPF - O(log n)vector<int> factorize(int x, vector<int>& spf) { vector<int> factors; while (x != 1) { factors.push_back(spf[x]); x = x / spf[x]; } return factors;}// Linear Sieve - O(n) time complexityvector<int> linearSieve(int N) { vector<int> lp(N + 1), pr; for (int i = 2; i <= N; i++) { if (lp[i] == 0) { lp[i] = i; pr.push_back(i); } for (int j = 0; j < pr.size() && pr[j] <= lp[i] && i * pr[j] <= N; j++) lp[i * pr[j]] = pr[j]; } return pr;}// Segmented Sieve for range [L,R]vector<bool> segmentedSieve(long long L, long long R) { // Generate primes up to sqrt(R) int limit = sqrt(R); vector<int> primes = simpleSieve(limit); // Mark primes in [L,R] vector<bool> isPrime(R - L + 1, true); if (L == 1) isPrime[0] = false; // Mark composites in range for (int p : primes) { // Find first multiple of p >= L long long firstMultiple = (L / p) * p; if (firstMultiple < L) firstMultiple += p; if (firstMultiple == p) firstMultiple += p; // Mark multiples of p in range for (long long j = firstMultiple; j <= R; j += p) isPrime[j - L] = false; } return isPrime;}// Usage example:// vector<bool> primes = segmentedSieve(1000000000, 1000001000);// First index (0) corresponds to number L// Time: O(√R + (R-L+1)log(log√R))// Space: O(√R + (R-L+1))