题目
思路
注意到
k
k
k为合数时答案为
0
0
0
k
<
72
k<72
k<72的时候容斥,
k
>
72
k>72
k>72的时候用
E
u
l
e
r
Euler
Euler筛
时空好紧,开小了RE,开大了MLE,调大用容斥的范围还会TLE……
代码
typedef long long ll;
typedef double db;
const int maxn=(int)3e7+9;
const db eps=1e-6;
const int mp=72;
int vis[maxn];
int pri[maxn];
int tot;
ll sl(int ppos,int n){
if(n<=0)return 0;
int t=1<<ppos;
ll ans=n;
for(int i=1;i<t;i++){
int sgn=1;
ll mul=1;
for(int j=0;j<ppos;j++)if(i&(1<<j)){
sgn*=-1;
mul*=pri[j];
}
ans+=n/mul*sgn;
}
return ans;
}
void sf(){
vis[1]=1;
for(int i=2;i<mp;i++){
if(!vis[i]){
pri[tot++]=i;
vis[i]=1;
}
for(int j=0;j<tot&&i*pri[j]<mp;j++){
vis[i*pri[j]]=1;
if(i%pri[j]==0){
break;
}
}
}
}
int main(){
int a,b,k;
scanf("%d%d%d",&a,&b,&k);
//printf("%d %d %d\n",a,b,k);
int sk=sqrt(k)+1;
for(int i=2;i<=sk&&i<k;i++){
if(k%i==0){
printf("0\n");
return 0;
}
}
sf();
if(k<mp){
int ppos=lower_bound(pri,pri+tot,k)-pri;
printf("%lld\n",sl(ppos,b/k)-sl(ppos,(a-1+k)/k-1));
}
else{
for(int i=0;i<mp;i++){
vis[i]=0;
}
tot=0;
int mx=b/k;
for(int i=2;i<=mx;i++){
if(!vis[i]&&i<k){
pri[tot++]=i;
vis[i]=1;
}
for(int j=0;j<tot&&pri[j]<k&&i*pri[j]<=mx;j++){
vis[i*pri[j]]=1;
if(i%pri[j]==0){
break;
}
}
}
int ans=0;
for(int i=(a+k-1)/k;i<=mx;i++){
if(!vis[i]){
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}