题解:
其中对于第
3
3
3 个操作,全程是只用了一次,因为用了第
3
3
3 次操作以后,
a
a
a 的值只会变得比
b
b
b 只大不小,那么必然后面的最优操作只能是不断地执行第
2
2
2 种操作。
抽象个数学模型,其中
a
a
a 先不断进行第
1
1
1 种操作达到了
a
′
a^{'}
a′,
b
b
b 不断进行操作达到了
b
′
b^{'}
b′,所用的总操作数就是
a
′
−
a
+
b
′
−
b
+
(
a
′
∣
b
′
)
−
b
′
+
1
a^{'} - a + b^{'} - b + (a^{'} | b^{'}) - b^{'} + 1
a′−a+b′−b+(a′∣b′)−b′+1,整理得到
a
′
+
(
a
′
∣
b
′
)
+
1
−
a
−
b
a ^ {'} + (a ^ {'} | b ^ {'}) + 1 -a - b
a′+(a′∣b′)+1−a−b,其中
1
−
a
−
b
1 -a -b
1−a−b 是常量,所以只需要优化前面
那么
a
′
a^{'}
a′ 从
a
a
a 向
b
b
b 不断进行迭代,此时我们要使
(
a
′
∣
b
′
)
(a ^ {'} | b ^ {'})
(a′∣b′) 最小,那么将
a
′
a^{'}
a′ 从高位向低位进行考虑,到了比如说第
j
j
j 位了,其中
a
′
a^{'}
a′ 此时第
j
j
j 位是
1
1
1,而
b
b
b 的第
j
j
j 位是
0
0
0,那么此时将
b
′
b^{'}
b′ 的第
j
j
j 位置为
1
1
1,并跳出循环就是所要的,而对于其他的情况,都置为
b
b
b 以前在对应该位的值
要点:
发现第
3
3
3 种操作的特殊性
如何归纳数学模型
如何使得
(
a
′
∣
b
′
)
(a^{'} | b^{'})
(a′∣b′) 达到最小值
code:
#include <bits/stdc++.h>
using namespace std;
#define db double
#define ll long long
#define pii pair<int,int>
#define mm(a,b) memset(a,b,sizeof(a))
#define rush() int T; cin >> T; while (T--)
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
const int N = 2e5 + 5;
const int M = (N << 2);
const int P = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int a, b;
int main()
{
ACCELERATE;
rush() {
cin >> a >> b;
int ans = b - a;
for (int i = a; i < b; i++) {
int k = 0;
for (int j = 20; j >= 0; j--) {
if (((i >> j) & 1) == 1 && ((b >> j) & 1) == 0) {
k ^= (1 << j);
ans = min(ans, i + (i | k) + 1 - a - b);
break;
}
if ((b >> j) & 1) k ^= (1 << j);
}
if (k == b) ans = min(ans, i + (i | k) + 1 - a - b);
}
cout << ans << endl;
}
return 0;
}