1. 程式人生 > 其它 >cf1330 D. Dreamoon Likes Sequences(計數)

cf1330 D. Dreamoon Likes Sequences(計數)

https://codeforces.com/contest/1330/problem/D

題意:

陣列 \(a_i\) 嚴格遞增,\(1\le a_i \le n\) 。用 \(a_i\) 構造 \(b_i\)\(b_1=a_1\)\(b_i = b_{i-1}\) \(xor\) \(a_i\)。要求 \(b_i\) 也嚴格遞增。問這樣的陣列 \(a_i\) 有多少

思路:

如果相鄰兩個 \(a_i\) 的二進位制最高位相同,那麼 \(b_i\) 將失去這一位。所以每個 \(a_i\) 的最高位都要不同

記最右邊為第 \(0\) 位,則 \(n\) 的最高位為 \(d=log_2(n)\) 。可以這樣構造出 \(a_i\)

:選1或0個最高位為 \(0\) 的數,再選1或0個最高位為 \(1\) 的數,一直選到 \(d\)

“選1或0個最高位為 \(i\) 的數” 有 \(2^i+1\) 種可能,“選1或0個最高位為 \(d\) 的數” 有 \((n-(1<<d)+1)+1\) 種可能。全部乘起來即可。注意全都選0個是不行的,所以 ans-1

#include <bits/stdc++.h>
using namespace std;

signed main()
{
    int T; cin >> T; while(T--)
    {
        int n, m; cin >> n >> m;
        int d = log2(n), ans = 1;
        for(int i = 0; i < d; i++)
            ans = 1ll * ans * (((1<<i)+1) % m) % m;
        ans = 1ll * ans * ((n - (1<<d) + 2) % m) % m;
        cout << (ans-1+m)%m << '\n';
    }

    return 0;
}