数学:洛谷P3601 签到题
数据上看显然从r−l≤10e6下手
先筛法筛出素数
再由欧拉函数
φ(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<bits/stdc++.h> #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; }

浙公网安备 33010602011771号