1. 程式人生 > >luogu P3327 [SDOI2015]約數個數和

luogu P3327 [SDOI2015]約數個數和

背景:

以下圖片均來自我的 P D F PDF 檔案,謝絕轉載。

題目傳送門:

https://www.luogu.org/problemnew/show/P3327

題意:

在這裡插入圖片描述

思路:

在這裡插入圖片描述
在這裡插入圖片描述

程式碼:

#include<cstdio>
#include
<cstring>
#include<algorithm> #define LL long long #define _ (int)5e4+10 using namespace std; int mu[_],prime[_]; bool bz[_]; int t=0; LL sum[_],p[_]; void init1(int ma) { mu[1]=sum[1]=1; bz[0]=bz[1]=true; for(int i=2;i<=ma;i++) { if(!bz[i]) prime[++t]=i,mu[i]=-1; for(int j=1
;j<=t&&(LL)i*prime[j]<=ma;j++) { bz[i*prime[j]]=true; if(!(i%prime[j])) { mu[i*prime[j]]=0; break; } mu[i*prime[j]]=-mu[i]; } sum[i]=sum[i-1]+mu[i]; } } void init2(int ma) { for(int i=1;i<=ma;i++) { int l=1,r; while(l<=i) { r=i/(i/l); p[i]
+=(LL)(r-l+1)*(i/l); l=r+1; } } } LL calc(int n,int m) { int l=1,r; LL tot=0; while(l<=min(n,m)) { r=min(n/(n/l),m/(m/l)); tot+=p[n/l]*p[m/l]*(sum[r]-sum[l-1]); l=r+1; } return tot; } int main() { int T,x,y; init1(_); init2(_); scanf("%d",&T); while(T--) { scanf("%d %d",&x,&y); printf("%lld\n",calc(x,y)); } }