YY的GCD

洛谷有, 卡快读

题面

神犇 YY 虐完数论后给傻× kAc 出了一题

给定 N, M 且 gcd(x,y) 为质数的 (x, y)(x,y) 有多少对。

输入格式

第一行一个整数 T 表述数据组数。

接下来 T 行,每行两个正整数,N, M。

输出格式

T 行,每行一个整数表示第 i 组数据的结果。

输入输出样例

输入1

2
10 10
100 100

输出1

30
2791
$ T = 10^4,N, M leq 10^7$ 

题解

设 F(n) 表示 gcd(x, y) == k的倍数 的(x, y)的对数, f(n) 表示 gcd(x, y) == k 的(x, y)的对数

$F(n) = sum_{n | d} f(d) = left lfloor frac {n} {k} ight floor imes left lfloor frac {m} {k} ight floor $

由莫比乌斯反演得, (f(n) = sum_{n | d} mu (frac {d} {n}) F(d))

变换区间, 左区间向上、右区间向下取整, 直接求 gcd(x / k, y / k) == 1, 即f(1) 为解

(f(1) = sum_{d = 1}^{left lfloor frac {min(n, m)} {k} ight floor} mu (d) imes left lfloor frac {n} {k} ight floor imes left lfloor frac {m} {k} ight floor)

(ans = sum_{p in prime} sum_{p | d} mu (frac {d} {p}) imes F(d))

设 d = k * p

(ans = sum_{p in prime} sum_{k = 1}^{frac {min(n, m)} {p} } mu (k) imes F(kp))

(ans = sum_{d = 1}^{min(n, m)} F(d) imes sum_{p in d_{prime}} mu (d))

带入 F(n) 分块可求, (sum_{p in d_{prime}} mu (d)) 预处理前缀和

//快读省略
const int N = 1e7 + 5;

int n, m = 1e7, _, k;
int prime[N], miu[N], cnt, a, b;
long long sum[N], x;
bool v[N];

void init() {
    miu[1] = 1;
    for (int i = 2; i <= m; ++i) {
        if (!v[i]) prime[++cnt] = i, miu[i] = -1;
        for (int j = 1; j <= cnt && prime[j] <= m / i; ++j) {
            v[i * prime[j]] = 1;
            if (i % prime[j] == 0) break;
            miu[prime[j] * i] = -miu[i];
        }
    }
    for (int i = 1; i <= cnt; ++i)
        for (int j = 1; j <= m / prime[i]; ++j) sum[prime[i] * j] += miu[j];

    for (int i = 2; i <= m; ++i) sum[i] += sum[i - 1];
}

int main() {
    init();
    for (scan(_); _; --_) {
        scan(a); scan(b); x = 0;
        if (a > b) swap(a, b);
        for (int l = 1, r; l <= a; l = r + 1) {
            r = min(b / (b / l), a / (a / l));
            x += (sum[r] - sum[l - 1]) * (b / l) * (a / l);
        }
        print(x); putchar('
');
    }
    return 0;
}

即 ans = sum_{}

原文地址:https://www.cnblogs.com/2aptx4869/p/13613179.html