P7586题解
这道题目一看数据范围就知道它是一道数学题,不过要怎样处理呢?
令
关键就在这里:对于所有
预处理完之后,计算
#include<ctime>
#include<cstdio>
#include<cctype>
#define ll long long
using namespace std;
ll read(){
char c;
ll x=0,f=1;
while(!isdigit(c=getchar()))
f-=2*(c=='-');
while(isdigit(c)){
x=x*10+f*(c-48);
c=getchar();
}
return x;
}
ll gcd(ll x,ll y){
while(x&&y){
ll z=x;
x=y;
y=z%y;
}
return x|y;
}
ll lcm(ll x,ll y){
return x/gcd(x,y)*y;
}
ll a,b,str[55];
ll f(ll x){//找最小的正整数使得不能整除x
ll t=2;
for(;;++t){
if(x%t)
break;
}
return t;
}
ll work(ll x){
ll tmp=1;
ll res=x*2;
for(ll i=2;i<43;++i){
tmp=lcm(tmp,i);
res+=x/tmp*(str[i+1]-str[i]);//在1~x中f(i)>tmp的有x/tmp个,而这些开始默认它为tmp,所以要改变
}
return res;
}
int main(){
a=read()-1;
b=read();
for(ll i=3;i<=43;++i)
str[i]=str[f(i)]+1;//预处理strength(i),实际上并不需要确切值,像这里其实处理的是strength(i)-1
printf("%lld",work(b)-work(a));
return 0;
}