nkoj8980 a * b 计数问题
题目描述:
设 \(f(n)=\sum\limits^{n-1}_{i=0}\sum\limits^{n-1}_{j=0}[ij\text{ mod }n\neq 0]\),求 \(g(n)=\sum\limits_{d\vert n}f(d)\)。
求 \(g(n)\) 对 \(2^{64}\) 取模的结果。
\(T\) 组数据,\(1\le T\le 20000,1\le n\le 10^9\)。
题目解法:
让我们重新定义 \(f\) 函数,注意到 \(f(n)=\sum\limits^{n-1}_{i=0}\sum\limits^{n-1}_{j=0}[ij\text{ mod }n=0]\) 积性,则 \(g(n)=\sum\limits_{d\vert n}d^2-\sum\limits_{d\vert n}f(n)\) 即为所求。
为什么积性证不来,可以打个表观察一下。
考虑 \(f(p^k)\)。
\[f(p^k)=2p^k-1+\sum\limits^{k-1}_{i=0}\sum\limits^{k-1}_{j=0}(\frac{p^k}{p^i}-\frac{p^k}{p^{i+1}})(\frac{p^k}{p^j}-\frac{p^k}{p^{j+1}})[i+j\ge k]
\]
\[f(p^k)=2p^k-1+\sum\limits^{k-1}_{i=0}\sum\limits^{k-1}_{j=0}(p^{k-i}-p^{k-i-1})(p^{k-j}-p^{k-j-1})[i+j\ge k]
\]
然后就预处理 \(\sqrt{n}\) 以内的质因数,对 \(n\) 质因数分解就完了,\(f(p^k)\) 可以在 \(O(k^2))\) 内求出,毕竟这不是瓶颈。
时间复杂度 \(O(T\frac{\sqrt{n}}{\ln n})\)。
#include <cstdio>
int Prime[40005], cnt;
inline unsigned long long f(int p, int k, int n) {
unsigned long long ans = 2 * n - 1;
for (unsigned long long i = 1, x = p; i < k; ++ i, x *= p)
for (unsigned long long j = 1, y = p; j < k; ++ j, y *= p)
if (i + j >= k) ans += 1ull * ((n - 1) / x - (n - 1) / (p * x)) * ((n - 1) / y - (n - 1) / (p * y));
return ans;
}
inline g(int n) {
int ans = 0;
for (int a = 0; a < n; ++ a)
for (int b = 0; b < n; ++ b) if (a * b % n == 0) ++ ans;
return ans;
}
int main() {
for (int i = 2; i <= 40000; ++ i) {
bool flag = true;
for (int j = 2; j * j <= i; ++ j)
if (i % j == 0) {flag = false; break;}
if (flag) Prime[++ cnt] = i;
}
int _;
scanf("%d", &_);
while (_ --) {
int n;
scanf("%d", &n);
unsigned long long ans = 1ull, ans2 = 1ull;
for (int i = 1; Prime[i] * Prime[i] <= n; ++ i)
if (n % Prime[i] == 0) {
int now = 1, r = 0;
unsigned long long x = 1ull, y = 1ull;
while (n % Prime[i] == 0) {
now *= Prime[i], ++ r, n /= Prime[i];
y += f(Prime[i], r, now);
x += 1ull * now * now;
}
ans *= y, ans2 *= x;
}
if (n != 1) ans *= 2ull * n, ans2 *= (1ull * n * n + 1ull);
printf("%llu\n", ans2 - ans);
}
}