题解:CF1554C Mikasa
感觉是一道很巧妙的题。
首先,由于仅当
接下来考虑其他情况,本题题意相当于构造一个自然数
对于
设将
所以问题相当于找出这个位
首先考虑找出从高到低第一个
若遍历后无法找到此位,就从低到高找到第一个
在判断过程中逐位记录答案即可。
code
#include<bits/stdc++.h>
using namespace std;
int T, n, m, a[50], b[50], cnta, cntb;
int main(){
cin >> T;
while(T--){
for(int i = 1; i <= cnta; i++) a[i] = 0;
for(int i = 1; i <= cntb; i++) b[i] = 0;
cnta = cntb = 0;
cin >> n >> m;
if(m < n){
cout << "0\n";
continue;
}
while(m){
a[++cnta] = (m&1);
m >>= 1;
}
while(n){
b[++cntb] = (n&1);
n >>= 1;
}
int res = 0, v = 0;
for(int i = cnta; i >= 1; i--){
res *= 2;
if(v) continue;
if(i > cntb) res += a[i];
else{
if(a[i] < b[i]) v = 1;
else res += (a[i] != b[i]);
}
}
if(v){
cout << res << '\n';
continue;
}
int s = 1;
res = 0;
for(int i = 1; i <= cnta+1; i++){
if(v) res += s*(a[i]!=b[i]);
else if(!a[i]) v = 1, res += s;
s = s*2;
}
cout << res << '\n';
}
return 0;
}