3994: [SDOI2015]约数个数和
3994: [SDOI2015]约数个数和
分析
题解见 https://blog.csdn.net/crzbulabula/article/details/54809145
http://www.cnblogs.com/zj75211/p/8298539.html
https://www.cnblogs.com/iwtwiioi/p/4986325.html
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 5 inline int read() { 6 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 7 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 8 } 9 10 const int N = 50010; 11 int pri[N],mu[N],tot; 12 LL f[N]; 13 bool nopri[N]; 14 15 void init() { 16 mu[1] = 1; 17 for (int i=2; i<=50000; ++i) { 18 if (!nopri[i]) pri[++tot] = i,mu[i] = -1; 19 for (int j=1; j<=tot&&i*pri[j]<=50000; ++j) { 20 nopri[i*pri[j]] = true; 21 if (i % pri[j] == 0) { 22 mu[i * pri[j]] = 0; 23 break; 24 } 25 mu[i * pri[j]] = -mu[i]; 26 } 27 } 28 for (int i=1; i<=50000; ++i) { 29 for (int pos,j=1; j<=i; j=pos+1) { 30 pos = i/(i/j); 31 f[i] += 1ll * (pos - j + 1) * (i / j); 32 } 33 mu[i] += mu[i-1]; 34 } 35 } 36 void solve() { 37 int n = read(),m = read(); 38 int mi = min(n,m); 39 LL ans = 0; 40 for (int pos,i=1; i<=mi; i=pos+1) { 41 pos = min(n/(n/i),m/(m/i)); 42 ans += 1ll * f[n/i] * f[m/i] * (mu[pos] - mu[i-1]); 43 } 44 printf("%lld\n",ans); 45 } 46 int main() { 47 init(); 48 int T = read(); 49 while (T--) solve(); 50 return 0; 51 }