链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4150
题解
这题题意不清,实际上,你可以默认
b
−
a
≤
1
0
7
b-a\leq10^7
b−a≤107
那么显然就是区间筛了
如果在区间
[
a
,
b
]
[a,b]
[a,b]中的一个数是合数,那么它的最小质因子肯定不超过
b
\sqrt b
b
利用这一点可以做区间筛,枚举
[
1
,
n
]
[1,\sqrt n]
[1,n]的素数,去筛掉它的倍数
注意倍数的范围是
m
a
x
(
2
,
⌈
n
p
r
i
m
e
i
⌉
)
∗
p
r
i
m
e
i
max(2,\lceil\frac{n}{prime_i}\rceil)*prime_i
max(2,⌈primein⌉)∗primei而非
⌈
n
p
r
i
m
e
i
⌉
p
r
i
m
e
i
\lceil\frac{n}{prime_i}\rceil prime_i
⌈primein⌉primei
因为它本身不应该被筛掉
代码
//区间筛
#include <bits/stdc++.h>
#define ll long long
#define maxn 10000010
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
ll prime[maxn], mark[maxn], mk[maxn], a, b, lis[maxn];
void shai()
{
ll i, j;
for(i=2;i<maxn;i++)
{
if(!mark[i])prime[++*prime]=i;
for(j=1;j<=*prime and i*prime[j]<maxn;j++)
{
mark[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-48;
return f*x;
}
void work()
{
ll i, j, ans=0, a=read(), b=read(), k=read(), s=read();
cl(mk), cl(lis);
for(i=1;prime[i]*prime[i]<=b;i++)for(j=max(2ll,(ll)ceil(1.0*a/prime[i]))*prime[i];j<=b;j+=prime[i])mk[j-a]=1;
for(i=a;i<=b;i++)if(!mk[i-a])lis[++*lis]=i;
for(i=1;i<=*lis-k+1;i++)if(lis[i+k-1]-lis[i]==s)ans++;
printf("%lld\n",ans);
}
int main()
{
int T=read();
shai();
while(T--)work();
return 0;
}