数学:洛谷P3601 签到题


原题传送门

数据上看显然从r?l10e6下手

先筛法筛出素数

 再由欧拉函数

φ(n)=n*(1-1/p1)(1-1/p2)(1-1/p3)*(1-1/p4)……(1-1/pn)

用根号r以内质数的筛出[l,r]所有数的欧拉函数即可

注意做个标记,没被质数筛过的[l,r]中的数就是大质数,此时φ(n)=n-1

#include
#define N 1000006
#define M 1000000000000
#define mod 666623333
long long p[N],a[N],vis[N];
bool prime[N];
using namespace std;
int main(){
    long long n,i,j,d,l,r,rr,x,s,ans,t;
    cin>>l>>r;rr=sqrt(r);d=r-l;
    for(i=0;i<=N-6;i++){prime[i]=true;vis[i]=i+l;}
    prime[1]=false;
    for(i=2;i<=rr;i++){
        if(prime[i]){
            for(j=i;j*i<=rr;j++){
                prime[j*i]=false;
            }
        }
    }
    n=0;
    for(i=2;i<=rr;i++){
        if(prime[i]) p[++n]=i;
    }
    for(i=0;i<=d;i++)a[i]=i+l;
    for(i=1;i<=n;i++){
        for(j=(l-1)/p[i]+1;j*p[i]<=r;j++){
            t=j*p[i];
            while(vis[t-l]%p[i]==0) vis[t-l]/=p[i];
            if(t>=l && t<=r) a[t-l]=a[t-l]*(p[i]-1)/p[i];
        }
    }
    for(i=0;i<=d;i++) if(vis[i]>1) a[i]=a[i]/vis[i]*(vis[i]-1);
    ans=0;
    for(i=0;i<=d;i++){
//        printf("%d:%d\n",l+i,a[i]);
        ans+=(i+l-a[i]);ans=(ans+mod)%mod;
    }
    cout<<ans;
    return 0;
}

#include#define N 1000006#define M 1000000000000#define mod 666623333long long p[N],a[N],vis[N];bool prime[N];using namespace std;int main(){long long n,i,j,d,l,r,rr,x,s,ans,t;cin>>l>>r;rr=sqrt(r);d=r-l;for(i=0;i<=N-6;i++){prime[i]=true;vis[i]=i+l;}prime[1]=false;for(i=2;i<=rr;i++){if(prime[i]){for(j=i;j*i<=rr;j++){prime[j*i]=false;}}}n=0;for(i=2;i<=rr;i++){if(prime[i]) p[++n]=i;}for(i=0;i<=d;i++)a[i]=i+l;for(i=1;i<=n;i++){for(j=(l-1)/p[i]+1;j*p[i]<=r;j++){t=j*p[i];while(vis[t-l]%p[i]==0) vis[t-l]/=p[i];if(t>=l && t<=r) a[t-l]=a[t-l]*(p[i]-1)/p[i];}}for(i=0;i<=d;i++) if(vis[i]>1) a[i]=a[i]/vis[i]*(vis[i]-1);ans=0;for(i=0;i<=d;i++){//printf("%d:%d\n",l+i,a[i]);ans+=(i+l-a[i]);ans=(ans+mod)%mod;}cout<