[SDOI2015]约数个数和
题目
尝试与思考
求
\[\sum_{i=1}^n\sum_{j=1}^md(ij)
\]
考虑设 \(T=ij\),那么就有
\[\text{ans}\;=\;\sum_{T=1}^{nm}d(T)\sum_{i=1}^{\frac{T}{m}\le i\le n}[i|T]
\]
然后,发现这个东西不可做了,这方法破产了...
考虑另外一种思路,由于我们有
\[d(ij)=\sum_{x|i}\sum_{y|j}[\gcd(x,y)=1]
\]
那么这个式子就是
\[\begin{aligned}
\text{ans}\;&=\;\sum_{i=1}^n\sum_{j=1}^m\sum_{x|i}\sum_{y|j}[\gcd(x,y)=1] \\
&=\;\sum_{x=1}^n\sum_{y=1}^m[\gcd(x,y)=1]\sum_{x|i}\sum_{y|j}1 \\
&=\;\sum_{x=1}^n\sum_{y=1}^m[\gcd(x,y)=1]\left\lfloor\frac{n}{x}\right\rfloor\left\lfloor\frac{m}{y}\right\rfloor \\
&=\;\sum_{i=1}^n\sum_{j=1}^m\left\lfloor\frac{n}{i}\right\rfloor\left\lfloor\frac{m}{j}\right\rfloor\sum_{x|i,x|j}\mu(x) \\
&=\;\sum_{x=1}^n\mu(x)\sum_{i=1}^{n/x}\sum_{j=1}^{m/x}\left\lfloor\frac{n}{ix}\right\rfloor\left\lfloor\frac{m}{jx}\right\rfloor
\end{aligned}
\]
我们令 \(G(T)=\sum_{i=1}^{T}\left\lfloor\frac{T}{i}\right\rfloor\),首先这个函数可以分块算,同时有
\[\begin{aligned}
\text{ans}\;=\;\sum_{x=1}^n\mu(x) G(\left\lfloor\frac{n}{x}\right\rfloor)G(\left\lfloor\frac{m}{x}\right\rfloor)
\end{aligned}
\]
考虑将 \(G()\) 预处理出来,对于答案也分块算,那么总复杂度就是 \(\mathcal O(n\sqrt n+T\sqrt n)\).
代码
# include <cstdio>
# include <algorithm>
using namespace std;
namespace Elaina{
# define rep(i,l,r) for(int i=l, i##_end_ = r; i <= i##_end_; ++ i)
# define fep(i,l,r) for(int i=l, i##_end_ = r; i >= i##_end_; -- i)
# define fi first
# define se second
# define Endl putchar('\n')
# define writc(x, c) fwrit(x), putchar(c)
// # define int long long
typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;
typedef unsigned int uint;
template<class T>inline T Max(const T x, const T y){return x < y ? y : x;}
template<class T>inline T Min(const T x, const T y){return x < y ? x : y;}
template<class T>inline T fab(const T x){return x < 0 ? -x : x;}
template<class T>inline void getMax(T& x, const T y){x = Max(x, y);}
template<class T>inline void getMin(T& x, const T y){x = Min(x, y);}
template<class T>T gcd(const T x, const T y){return y ? gcd(y, x % y) : x;}
template<class T>inline T readin(T x){
x=0; int f = 0; char c;
while((c = getchar()) < '0' || '9' < c) if(c == '-') f = 1;
for(x = (c ^ 48); '0' <= (c = getchar()) && c <= '9'; x = (x << 1) + (x << 3) + (c ^ 48));
return f ? -x : x;
}
template<class T>void fwrit(const T x){
if(x < 0)return putchar('-'), fwrit(-x);
if(x > 9)fwrit(x / 10); putchar(x % 10 ^ 48);
}
}
using namespace Elaina;
const int maxn = 50000;
int prime[maxn + 5], pcnt;
int sie[maxn + 5], mu[maxn + 5];
ll pre[maxn + 5];
inline void sieve(){
mu[1] = pre[1] = 1;
rep(i, 2, maxn){
if(!sie[i]) prime[++ pcnt] = i, mu[i] = -1;
for(int j = 1; j <= pcnt && i * prime[j] <= maxn; ++ j){
sie[i * prime[j]] = 1;
if(i % prime[j] == 0){
mu[i * prime[j]] = 0; break;
}
mu[i * prime[j]] = -mu[i];
}
pre[i] = pre[i - 1] + mu[i];
}
}
ll G[maxn + 5];
inline ll g(const int n){
ll ret = 0;
for(int l = 1, r; l <= n; l = r + 1){
r = n / (n / l);
ret += (r - l + 1) * (n / l);
}
return ret;
}
int n, m;
signed main(){
sieve();
rep(i, 1, maxn) G[i] = g(i);
rep(cas, 1, readin(1)){
n = readin(1), m = readin(1);
if(n > m) swap(n, m);
ll ans = 0;
for(int l = 1, r; l <= n; l = r + 1){
r = Min(n / (n / l), m / (m / l));
ans += 1ll * (pre[r] - pre[l - 1]) * G[n / l] * G[m / l];
}
writc(ans, '\n');
}
return 0;
}
用到の一些trick
首当其冲的是这个结论
\[d(ij)=\sum_{x|i}\sum_{y|j}[\gcd(x,y)=1]
\]
考虑怎么证明呢?我们设对于质数 \(p\),\(i\) 有 \(a\) 个,\(j\) 有 \(b\) 个,那么显然的,\(ij\) 就有 \(a+b\) 个,同时,在因子的选择上,\(ij\) 就有 \(a+b+1\) 中选择方案,而如果我们要保证 \(\gcd(x,y)=1\),那么对于 \(x,y\) 来说,最多只有一边会有 \(p\) 这个因子,那么对于只有 \(x\) 有的情况来说,有 \(a+1\) 种,对于只有 \(y\) 有的情况,就是 \(b+1\),同时还要减去重复算的两边都没有选择 \(x\) 的一种,就是 \(a+b+1+1-1=a+b+1\),所以这个可以等价.
其次,是 \(\gcd(x,y)=1\Leftrightarrow\sum_{i|x,i|y}\mu(i)=1\)
其实就是
\[\sum_{d|n}\mu(d)=
\begin{cases}
1,n=1 \\
0,n>1
\end{cases}
\]
如果 \(n=1\),那么显然.
考虑对于其他情况,设 \(n=p_1^{a_1}..p_k^{a_k}\),那么在 \(n\) 的所有因子中,\(\mu\) 值不为零的只有所有质因子次数都为 \(1\) 的因子,其中质因数个数为 \(r\) 个的因子有 \({k\choose r}\) 个,那么就有
\[\begin{aligned}
\sum_{d|n}\mu(d)&={k\choose 0}-{k\choose 1}+{k\choose 2}+...+(-1)^k{k\choose k} \\
&=\sum_{i=0}^k(-1)^i{k\choose i} \\
&=(1-1)^k=0
\end{aligned}
\]
最后一步由二项式定理:
\[(x+y)^z=\sum_{i=0}^n{z\choose i}x^iy^{z-i}
\]
给出.