P1835
终于想起来发博客了,呃呃呃呃呃呃
这题不难,但要看到 1≤L≤R<231和R−L≤106。
我们可以考虑先把<216的素数先筛出来,然后再把区间里的合数筛光。
然后……就没有然后了。
上代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+5;
int l,r;
int prime[maxn],cnt,ans;
bool vis[maxn];
void s() {
for(int i=2; i<=50000; ++i) {
if(!vis[i])prime[++cnt]=i;
for(int j=1; i*prime[j]<=50000; j++) {
vis[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
signed main() {
cin>>l>>r;
l=(l==1?2:l);//sb hack
s();
memset(vis,0,sizeof(vis));
for(int i=1; i<=cnt; ++i) {
int p=prime[i],start=((l+p-1)/p*p>2*p?(l+p-1)/p*p:2*p);
for(int j=start; j<=r; j+=p)vis[j-l+1]=1;
}
for(int i=1; i<=r-l+1; ++i)if(!vis[i])ans++;
cout<<ans<<endl;
}

浙公网安备 33010602011771号