Codeforces Round 949 (Div. 2) B
模拟:区间或
i代表左边的当前进行的数字位置,j表示在这个位置进行多少次操作
0
∣
1
0|1
0∣1
0
∣
1
∣
2
0|1|2
0∣1∣2
1
∣
2
∣
3.....
1|2|3.....
1∣2∣3.....
所以我们可以确定
一个左边界
l
=
m
a
x
(
0
,
i
−
j
)
l = max(0, i - j)
l=max(0,i−j),一个右边界
r
=
i
+
j
r = i + j
r=i+j
如何对一个区间进行一次或的操作呢
我们假设两个二进制数
0110001111
0110 001111
0110001111
0110100000
0110 100000
0110100000
我们可以发现,对这个区间进行或的时候,在进位的那一个数字,后面所有的数字都为1,也就是0110 111111.
代码
#include <bits/stdc++.h>
#define vi vector<int>
#define vpi vector<pair<int, int>>
using namespace std;
using ll = long long;
constexpr int N = 110;
void solve()
{
int n, m;
cin >> n >> m;
int l = max(0, n - m), r = n + m;
if(l == r) cout << l << endl;
for(int i = 30; i >= 0; i --) {
if((r >> i & 1) && !(l >> i & 1)) {
cout << (l | ((1ll << i + 1) - 1)) << endl;
return;
}
}
}
signed main()
{
int T = 1;
cin >> T;
while(T --) solve();
}