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 }

 

posted @ 2018-06-25 21:17  MJT12044  阅读(206)  评论(0编辑  收藏  举报