1 2 3 4 5 2 2 6 4 10 3 6 3 12 15 4 4 12 4 20
時間複雜度近似O(n)。複雜度式子是\(\sum_{i=1}^{n}\sqrt{\lfloor\frac{n}{i}\rfloor}\)這個積分後差很少是O(n),通過測試,係數約爲2.6左右,所以是跑的過的html
#include<bits/stdc++.h> #define N 10010000 using namespace std; inline void read(int &x) { x=0; static int p;p=1; static char c;c=getchar(); while(!isdigit(c)){if(c=='-')p=-1;c=getchar();} while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();} x*=p; } const long long mod=20101009; int n,m; bool vis[N]; int cnt,prim[N],mu[N]; long long sum[N]; void get_mu(int maxn) { mu[1]=1; for(int i=2;i<=maxn;i++) { if(!vis[i]){prim[++cnt]=i;mu[i]=-1;} for(int j=1;j<=cnt&&prim[j]*i<=maxn;j++) { vis[i*prim[j]]=1; if(i%prim[j]==0)break; else mu[i*prim[j]]=-mu[i]; } } for(int i=1;i<=maxn;i++)(sum[i]=sum[i-1]+1ll*mu[i]*1ll*i%mod*1ll*i%mod)%=mod; } int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); read(n);read(m); int max_rep=0; get_mu(max_rep=min(n,m)); long long ans=0; long long inv2=(mod+1ll)/2ll; long long summ=0; for(int d=1;d<=max_rep;d++) { int maxx=n/d,maxy=m/d,minn=min(maxx,maxy); summ=0ll; for(int l=1,r;l<=minn;l=r+1ll) { r=min(maxx/(maxx/l),maxy/(maxy/l)); (summ+=(sum[r]-sum[l-1])%mod*(((1ll+maxx/l)%mod*1ll*(maxx/l)%mod*inv2%mod)%mod)%mod*(((1ll+maxy/l)%mod*1ll*(maxy/l)%mod*inv2%mod)%mod)%mod)%=mod; } (ans+=summ*1ll*d)%=mod; } cout<<(ans%mod+mod)%mod<<endl; return 0; }