1. 程式人生 > 其它 >uva12716 GCD XOR(數論、xor、列舉)

uva12716 GCD XOR(數論、xor、列舉)

題意:

多組測試,每次輸入 \(n\),問有多少對整數 \((a,b)\) 滿足 \(1\le a\le b \le n\)\(\gcd (a,b) = a\oplus b\)

\(T\le 1e4, n\le 3e7\)

思路:

\(g=\gcd (a,b)\) ,則根據題目條件必有 \(a-b=g\)

證明:

首先要知道一個性質:\(a-b\le a\oplus b(=g)\)

\(a=k_1g, b=k_2g\)。當 \(k_1=k_2\) 時題目條件不可能成立,故不用考慮。當 \(k_1>k_2\) 時,\(a-b\ge g\)

綜上,\(a-b=g\)

接下來列舉 \(g\)

\(a=kg(k\ge 2)\) ,判斷 \(b\) 是否合法。怎麼判斷呢?因為 \(b=(k-1)g\),所以 \(\gcd(a,b)=g\) 一定滿足,故只需判斷是否有 \(g=a\oplus b\)

預處理答案,每次詢問直接輸出。

const signed N = 3e7 + 3;
int ans[N];

signed main() {
    iofast;

    for(int g = 1; g <= N/2; g++)
        for(int a = g + g; a < N; a += g) {
            int b = a - g;
            if((a ^ b) == g) ans[a]++; //注意括號
        }
    for(int i = 1; i < N; i++) ans[i] += ans[i-1];

    int q; cin >> q;
    for(int i = 1; i <= q; i++) {
        int n; cin >> n;
        cout << "Case " << i << ": " << ans[n] << endl;
    }
}