Challenges Programming Contest: The number of prime numbers in the interval

Subject to the effect

Here Insert Picture Description

Problem-solving ideas

The complexity of the Egyptian-style screening method is O ( n l O g l O g n ) The (nloglogn) a. But the scope of this problem is 1 0 12 10^{12} can not be used angstroms type sieve. And space complexity is not allowed. But we can learn from the Egyptian-style ideological sieve method, which is based on two facts;

  • (1) b b Number engagement withinthe smallestprime factor must not exceed b \sqrt b . which is x [ a , b ) x \in [a,b) and x x is a composite number, so it must be less than the quality factor b \sqrt b
  • (2) make [ 2 , b ) [2,\sqrt b) Primes table, and from [ a , b ) [a,b) the cross out all multiples of a prime number, the rest is a prime number.

So to understand this question, we need to maintain a

  • i s _ p r i m e 1 [ i ] is\_prime1[i] : is used to determine i [ 2 , b ) i \in [2,\sqrt b) Whether the number is a prime number within the range.

Since digital too, in order to save space. We maintain a

  • i s _ p r i m e 2 [ i a ] is\_prime2[i-a] : to judge i [ a , b ) i \in[a, b) whether it is a prime number.

Code

#include<iostream>
using namespace std;
typedef long long ll;
const int MAXN = 1000000+5;
ll is_prime1[MAXN];
ll is_prime2[MAXN];

void get_primes(ll a, ll b)
{
	// ------------初始化 --------------
    for(ll i=0; i*i<b; i++)
        is_prime1[i] = 1;
    is_prime1[0] = is_prime1[1] = 0;

    for(ll i=a; i<b; i++)
        is_prime2[i-a] = 1;
	// ---------------------------------
	
    for(ll i=2; i*i<b; i++)
    {
        if(is_prime1[i])
        {
        	// 筛is_primes1
            for(ll j=(ll)2*i; j*j<b; j+=i)
                is_prime1[j] = 0;
                
			// 筛is_primes2
            for(ll j=(ll)(a-1+i)/i*i; j<b; j+=i)
                is_prime2[j-a] = 0;
        }
    }
}
int main()
{
    ll a, b;
    cin >> a >> b;

    get_primes(a, b);
    ll ans = 0;
    for(ll i=a; i<b; i++)
    {
        if(is_prime2[i-a])
            ans++;
    }
    cout << ans << endl;
}

Knowledge Point

  • The above code in such a line j = (ll)(a-1+i)/i*i. ( a 1 + i ) / i (a-1+i)/i is a / i a/i rounded up, so this effect is obtained by the first computing &gt; = a &gt;=a of i i multiples.

Guess you like

Origin blog.csdn.net/Wangpeiyi9979/article/details/93741209