标签:display == code lld [1] ons line amp std
\(T\) 次询问有多少个数对 \((x,y)\) 满足 \(a≤x≤b,c≤y≤d\) 且 \(gcd(x,y) = k\)。
假设 \(n<m\)
\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[gcd(i,j)=k]\\sum\limits_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{k}\rfloor}[gcd(i,j)=1]\\sum\limits_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{k}\rfloor}\sum\limits_{d|gcd(i,j)}\mu(d)\\sum\limits_{d=1}^{\lfloor\frac{n}{k}\rfloor}\mu(d){\left\lfloor\frac{n}{kd}\right\rfloor}{\left\lfloor\frac{m}{kd}\right\rfloor}\]
设 \(n'={\left\lfloor\frac{n}{k}\right\rfloor},m'={\left\lfloor\frac{m}{k}\right\rfloor}\)
\[\sum\limits_{d=1}^{n'}\mu(d){\left\lfloor\frac{n'}{d}\right\rfloor}{\left\lfloor\frac{m'}{d}\right\rfloor}\]
欧拉筛 + 整除分块 + 容斥。
#include <cstdio>
const int N = 50005;
int a, b, c, d, k, T, tot, np[N], p[N], mu[N], sum[N];
int min(int x, int y) {
return x < y ? x : y;
}
void getmu(int n) {
np[1] = mu[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!np[i]) p[++tot] = i, mu[i] = -1;
for (int j = 1; j <= tot && p[j] * i <= n; ++j) {
np[p[j]*i] = 1;
if (i % p[j] == 0) {
mu[p[j]*i] = 0;
break;
} mu[p[j]*i] = -mu[i];
}
}
for (int i = 1; i <= n; ++i) sum[i] = sum[i-1] + mu[i];
}
long long calc(int n, int m) {
long long res = 0;
n /= k, m /= k;
if (n > m) n ^= m, m ^= n, n ^= m;
for (int l = 1, r; l <= n; l = r + 1) {
r = min(n / (n / l), m / (m / l));
res += 1LL * (sum[r] - sum[l-1]) * (n / l) * (m / l);
}
return res;
}
int main() {
scanf("%d", &T), getmu(5e4);
while (T--) {
scanf("%d%d%d%d%d", &a, &b, &c, &d, &k);
printf("%lld\n", calc(b, d) - calc(a - 1, d) - calc(b, c - 1) + calc(a - 1, c - 1));
}
return 0;
}
标签:display == code lld [1] ons line amp std
原文地址:https://www.cnblogs.com/fly-in-milkyway/p/9973678.html