题目大意
求[l,r]区间phi函数和。
l和r均在10^12内,而l和r的差在10^6内。
筛
phi都知道怎么求了。
一个10^12的数至多一个大于10^6的质因子。
筛出10^6内所有质因数,然后枚举每个质因数。
用这个质因数去[l,r]筛。
最后再扫一遍判断大于10^6的质因子的情况。
#include<cstdio>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn=1000000+10,mo=666623333;
int pri[maxn];
ll phi[maxn],pp[maxn];
bool bz[maxn];
int k,t,n,m,top,ans;
ll i,j,l,r;
int main(){
scanf("%lld%lld",&l,&r);
fo(i,l,r) phi[i-l+1]=pp[i-l+1]=i;
fo(i,2,maxn-10){
if (!bz[i]) pri[++top]=i;
fo(j,1,top){
if ((ll)i*pri[j]>maxn-10) break;
bz[i*pri[j]]=1;
if (i%pri[j]==0) break;
}
}
fo(i,1,top){
t=pri[i];
fo(j,ceil((db)l/t),r/(ll)t){
phi[j*t-l+1]=(ll)phi[j*t-l+1]/t*(t-1);
while (pp[j*t-l+1]%t==0) pp[j*t-l+1]/=t;
}
}
fo(i,l,r)
if (pp[i-l+1]>maxn-10) phi[i-l+1]=(ll)phi[i-l+1]/pp[i-l+1]*(pp[i-l+1]-1);
fo(i,l,r) phi[i-l+1]=i-phi[i-l+1];
ans=0;
fo(i,l,r) (ans+=(phi[i-l+1]%mo))%=mo;
printf("%d\n",ans);
}