# bzoj3994 [SDOI2015]约数个数和

【题解】

# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

int T, n, m;

const int F = 50000;
bool isnp[F + 10];
int p[F/3], pn=0, mu[F + 10];
ll s[F + 10], f[F + 10];

inline ll gF(int n) {
ll ret = 0;
for (int i=1, lst; i<=n; i=lst+1) {
lst = n/(n/i);
ret = ret + (ll)(n/i) * (lst-i+1);
}
return ret;
}

inline ll gG(int n, int m) {
if(n > m) swap(n, m);
ll ret = 0;
for (int i=1, lst; i<=n; i=lst+1) {
lst = min(n/(n/i), m/(m/i));
ret += (ll)(s[lst]-s[i-1])*(f[n/i]*f[m/i]);
}
return ret;
}

int main() {
mu[1] = 1;
for (int i=2; i<=F; ++i) {
if(!isnp[i]) {
p[++pn] = i;
mu[i] = -1;
}
for (int j=1; j<=pn && i*p[j] <= F; ++j) {
isnp[i*p[j]] = 1;
if(i%p[j] == 0) {
mu[i*p[j]] = 0;
break;
}
mu[i*p[j]] = -mu[i];
}
}

for (int i=1; i<=F; ++i) s[i] = s[i-1] + mu[i], f[i] = gF(i);

scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
printf("%lld\n", gG(n, m));
}

return 0;
}
View Code
posted @ 2017-04-26 23:02  Galaxies  阅读(196)  评论(0编辑  收藏  举报