[學習筆記][SDOI2015]約數個數和
阿新 • • 發佈:2021-01-09
題目
嘗試與思考
求
\[\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} \]給出.