题目链接戳这里:https://www.luogu.org/problemnew/show/P1865
题目叫A%B???其实是给n次询问,询问[l,r]之间有多少个素数。
没试过暴力,1e6次询问肯定T啊!,询问次数很多,我们就需要优化询问的速度,我们想到前缀和(询问复杂度是O(1))
我只写了一个普通线性筛,因为我只会这个(抄板子),然后就for一遍造一下前缀和。
给代码给代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
int sum[maxn];
int isprime[maxn];
int su[maxn];
int cnt;
void prime()
{
cnt=1;
memset(isprime,1,sizeof(isprime));
isprime[0]=isprime[1]=0;
for(int i=2;i<maxn;i++)
{
if(isprime[i])
su[cnt++]=i;
for(int j=1;j<cnt&&su[j]*i<maxn;j++)
{
isprime[su[j]*i]=0;//筛掉小于等于i的素数和i的积构成的合数
if(!(i%su[j]))
{
break;
}
}
}
memset(isprime,0,sizeof(isprime));
for(int i=1;i<cnt;i++)
{
isprime[su[i]] = true;
}
}
void init()
{
memset(sum,0,sizeof(sum));
prime();
for(int i=1;i<maxn;i++)
{
if(isprime[i])
{
sum[i]++;
}
sum[i] += sum[i-1];
}
}
int main()
{
init();
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
int l,r;
cin>>l>>r;
if(l<1 || l>m || r<1 || r>m || r<l)
{
cout<<"Crossing the line"<<endl;
}
else
{
cout<<sum[r]-sum[l-1]<<endl;
}
}
return 0;
}
sum[i]++应该是sum[i] = 1,但是这里没影响,因为只会sum[i]++一次。