[SDOI2015]約數個數和 [莫比烏斯反演]
阿新 • • 發佈:2018-12-16
用整除分塊預處理
發現對於連續的d , n/d的取值一樣 , 也就是說 的取值一樣 , 然後就可以整除分塊做了
#include<bits/stdc++.h> #define N 50050 #define LL long long using namespace std; int T,n,m,tot; LL s_mu[N],s_f[N]; int mu[N],p[N],isp[N]; void Solve(){ scanf("%d%d",&n,&m); if(n>m) swap(n,m); LL ans = 0; for(int l=1,r;l<=n;l=r+1){ int x1=n/l,x2=m/l; r = min(n/x1,m/x2); ans += (s_mu[r]-s_mu[l-1]) * s_f[x1] * s_f[x2]; } printf("%lld\n",ans); } int main(){ mu[1]=s_mu[1]=1; for(int i=2;i<=N-50;i++){ if(!isp[i]) p[++tot]=i,mu[i]=-1; for(int j=1;j<=tot;j++){ if(i*p[j]>N-50) break; isp[i*p[j]]=1; if(i%p[j]==0) break; mu[i*p[j]] = -mu[i]; } s_mu[i] = s_mu[i-1] + mu[i]; } for(int i=1;i<=N-50;i++){ int ans=0; for(int l=1,r;l<=i;l=r+1){ r = i/(i/l); ans += (r-l+1) * (i/l); } s_f[i] = ans; } scanf("%d",&T); while(T--) Solve(); return 0; }