link
位运算 思维 middle
题意
思路
注意到
c
c
c 数列是单调递增的,而
c
i
=
c
i
−
1
x
o
r
a
i
c_i = c_{i-1} \ xor\ a_i
ci=ci−1 xor ai,由xor的性质,
c
i
−
1
c_{i-1}
ci−1 二进制下的位数一定小于
a
i
a_i
ai (因为比如1000 xor 1011 = 0011小于1000)
也就是说,
a
1
,
a
2
,
a
3
.
.
.
a_1,a_2,a_3...
a1,a2,a3... 每个数的位数不能相同,即 [1], [2, 3], [4, 5, 6, 7], […] 每个集合中最多取一个数。
例如
d
=
5
d=5
d=5 时, [1], [2, 3], [4, 5],方案为 2 * 3 * 3 - 1 = 17种
代码
int d, m;
void solve() {
cin >> d >> m;
int ans = 1;
int tmp = d;
vector<int> v;
for(int i = 1; i <= tmp; i <<= 1) {
v.push_back(i+1);
tmp -= i;
}
if(tmp) v.push_back(tmp + 1);
for(int i = 0; i < v.size(); i++) {
ans = ans * v[i] % m;
}
if(!ans) ans = m - 1;
else ans--;
cout << ans << endl;
}