【Luogu P2257】 YY的GCD
題目連結:
題目大意:
快速求:
\[\sum_{p\in Prime}\sum_{i=1}^{n}\sum_{j=1}^{m}\left[\operatorname{gcd}(i,j)==p\right] \]
正文:
按照莫比烏斯反演的常規套路,將式子化簡成我們能接受的時限:
\[\begin{aligned}\sum_{p\in Prime}\sum_{i=1}^{n}\sum_{j=1}^{m}\left[\operatorname{gcd}(i,j)==p\right] &=\sum_{p\in Prime}\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{p}\rfloor}\left[\operatorname{gcd}(i,j)==1\right]\\&=\sum_{p\in Prime}\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{p}\rfloor}\sum_{d|\operatorname{gcd}(i,j)}\mu(d)\\&=\sum_{p\in Prime} \sum_{d=1}\mu(d)\sum_{d|i}^{\lfloor\frac{n}{p}\rfloor}\sum_{k|j}^{\lfloor\frac{m}{p}\rfloor}1\\&=\sum_{p\in Prime}\sum_{d=1}\mu(d)\left\lfloor\frac{n}{pd}\right\rfloor\left\lfloor\frac{m}{pd}\right\rfloor\end{aligned} \]
設 \(k=pd\) 列舉 \(k\):
\[\begin{aligned}\sum_{p\in Prime}\sum_{d=1}\mu(d)\left\lfloor\frac{n}{pd}\right\rfloor\left\lfloor\frac{m}{pd}\right\rfloor&=\sum_{k=1}\left\lfloor\frac{n}{k}\right\rfloor\left\lfloor\frac{m}{k}\right\rfloor\sum_{p|k,p\in Prime}\mu(\frac{k}{p})\end{aligned} \]
預處理 \(\mu(\frac{k}{p})\)
程式碼:
稍微卡卡常就能過了。
inline void prework() { miu[1] = 1; for (int i = 2; i <= N - 10; i++) { if(!vis[i]) {pri[++cnt] = i, miu[i] = -1;} for (int j = 1; j <= cnt && pri[j] * i <= N - 10; j++) { vis[pri[j] * i] = 1; if (i % pri[j] == 0) { miu[i * pri[j]] = 0; break; } else miu[i * pri[j]] = -miu[i]; } } for (int i = 1; i <= cnt; i++) for (int j = 1; j * pri[i] <= N - 10; j++) sum[j * pri[i]] += miu[j]; for (int i = 1; i <= N - 10; i++) sum[i] += sum[i - 1]; } int main() { prework(); for (read(t); t--; ) { ans = 0LL; read(n);read(m); if(n > m) { ll c = n; n = m; m = c; } for (register int l = 1, r; l <= n; l = r + 1) { r = min (n / (n / l), m / (m / l)); ans += (sum[r] - sum[l - 1]) * (n / l) * (m / l); } print(ans); } return 0; }