M - Help Hanzo LightOJ - 1197 (a large prime number sieve interval)

Solution: Interval prime issue. Notes that a and b ranges from 1 << 31, so the direct violence is certainly not hit the table. If a number is a composite number, his two factors either two sqrt (x), or on the distribution sqrt (x) at both ends, so we can put after sqrt (n) according to the number before sqrt (n) the prime number to sieve out.

First of all primes were 1e6's play table. Then for each of l, r, first find the first number greater than or equal to l, then out according to prime just sieve has been accumulated until r, so that the number of co-factor can range to the tag on 1e6. Note that we save time array to minus l, so long as the array open to 1e5 on it. Note that when l = 1, 1 is not a prime number, special sentenced to it.

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1E6+7;
bool primes[N];
ll  pre[N];
ll pos=0;
ll mp[100000+7];
void inint(){
    ll maxxn=1e6;
    primes[1]=1;
    primes[2]=0;
    for(ll i=2;i<=maxxn;i++){
        if(!primes[i]) pre[++pos]=i;
        for(ll j=1;j<=pos&&i*pre[j]<=maxxn;j++){
            primes[i*pre[j]]=1;
            if(i%pre[j]==0) break;
        }
    }
}
int main(){
    inint();   
    ll t;
    cin>>t;
    int time=0;
    while(t--){
        memset(mp,0,sizeof mp);
        int l,r;
        cin>>l>>r;
        for(ll i=1;i<=pos;i++){
            ll c=l/pre[i];
            if(l%pre[i]!=0) c++;
            for(ll j=c*pre[i];j<=r;j+=pre[i]){
                if(j==pre[i]) continue ;
                mp[j-l]=1;
            }
        }
        ll ans=0;
        for(ll i=l;i<=r;i++){
            if(!mp[i-l]) ans++;
        }
        if(l==1) ans--;
        printf("Case %d: %lld\n",++time,ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/Accepting/p/12601524.html