题目描述

设d(x)为x的约数个数,给定N、M,求 i = 1 n j = 1 m d ( i j ) \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}d(ij) i=1nj=1md(ij)

输入格式

输入文件包含多组测试数据。第一行,一个整数T,表示测试数据的组数。接下来的T行,每行两个整数N、M。

输出格式

T行,每行一个整数,表示你所求的答案。

输入输出样例
输入 #1

2
7 4
5 6

输出 #1

110
121
说明/提示
1<=N, M<=50000

1<=T<=50000

分析

首先有一个结论(别看我我不会证
d ( i j ) = <munder> x i </munder> <munder> y j </munder> [ g c d ( x , y ) = = 1 ] d(ij) =\sum\limits_{x|i}\sum\limits_{y|j}[gcd(x,y)==1] d(ij)=xiyj[gcd(x,y)==1]
于是
a n s = i = 1 n j = 1 m d ( i j ) = i = 1 n j = 1 m <munder> x i </munder> <munder> y j </munder> [ g c d ( x , y ) = = 1 ] = i = 1 n j = 1 m <munder> x i </munder> <munder> y j </munder> <munder> k x , k y </munder> μ ( k ) = k = 1 n μ ( k ) i = 1 <mstyle mathsize="0&#46;5em"> <mstyle displaystyle="true" scriptlevel="0"> n k </mstyle> </mstyle> <mstyle displaystyle="true" scriptlevel="0"> n k d </mstyle> j = 1 <mstyle mathsize="0&#46;5em"> <mstyle displaystyle="true" scriptlevel="0"> m k </mstyle> </mstyle> <mstyle displaystyle="true" scriptlevel="0"> m k j </mstyle> ans = \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}d(ij)= \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\sum\limits_{x|i}\sum\limits_{y|j}[gcd(x,y)==1]=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\sum\limits_{x|i}\sum\limits_{y|j}\sum\limits_{k|x,k|y}\mu(k)=\sum\limits_{k=1}^{n}\mu(k)\sum\limits_{i=1}^{{\tiny\left\lfloor\dfrac{n}{k}\right\rfloor}}\left\lfloor\dfrac{n}{kd}\right\rfloor\sum\limits_{j=1}^{{\tiny\left\lfloor\dfrac{m}{k}\right\rfloor}}\left\lfloor\dfrac{m}{kj}\right\rfloor ans=i=1nj=1md(ij)=i=1nj=1mxiyj[gcd(x,y)==1]=i=1nj=1mxiyjkx,kyμ(k)=k=1nμ(k)i=1knkdnj=1kmkjm
g ( n ) = i = 1 n <mstyle displaystyle="true" scriptlevel="0"> n i </mstyle> g(n) = \sum\limits_{i=1}^{n}\left\lfloor\dfrac{n}{i}\right\rfloor g(n)=i=1nin,于是
a n s = k = 1 n μ ( k ) g ( <mstyle displaystyle="true" scriptlevel="0"> n k </mstyle> ) g ( <mstyle displaystyle="true" scriptlevel="0"> m k </mstyle> ) ans = \sum\limits_{k=1}^{n}\mu(k)*g(\left\lfloor\dfrac{n}{k}\right\rfloor)*g(\left\lfloor\dfrac{m}{k}\right\rfloor) ans=k=1nμ(k)g(kn)g(km),除法分块即可。
总复杂度 O ( n n + T n ) O(n\sqrt{n}+T\sqrt{n}) O(nn +Tn )

代码如下

#include <bits/stdc++.h>
#define N 50005
#define LL long long
using namespace std;
int g[N], mu[N], s[N], x[N], p[N], cnt, maxn = 50000;
LL ans, z = 1;
int main(){
	int i, j, n, m, t, l, r, T;
	mu[1] = 1;
	for(i = 2; i <= maxn; i++){
		if(!x[i]) x[i] = 1, p[++cnt] = i, mu[i] = -1;
		for(j = 1; j <= cnt; j++){
			t = i * p[j];
			if(t > maxn) break;
			x[t] = 1;
			if(i % p[j] == 0) break;
			mu[t] = -mu[i];
		}
	}
	for(i = 1; i <= maxn; i++) s[i] = s[i - 1] + mu[i];
	for(i = 1; i <= maxn; i++){
		for(l = 1; l <= i; l = r + 1){
			r = i / (i / l);
			g[i] += (r - l + 1) * (i / l);
		}
	} 
	scanf("%d", &T);
	while(T--){
		scanf("%d%d", &n, &m);
		if(n > m) swap(n, m);
		ans = 0;
		for(l = 1; l <= n; l = r + 1){
			r = min(n / (n / l), m / (m / l));
			ans += z * (s[r] - s[l - 1]) * g[n / l] * g[m / l];
		}
		printf("%lld\n", ans);
	}
	return 0;
}