D2. Max Sum OR (Hard Version) (应该写的比较清晰)
自己写的时候码力不足,比较痛苦,但是没找到写的简单清晰的代码可以参考
于是憋了一下午写了一份,供他人参考
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<set>
using namespace std;
#define ffp(x,y,z) for(int (x)=(y);(x)<=(z);(x++))
#define ll long long int
#define q_ read()
#define pii pair<int,int>
const ll MOD = 998244353;
const ll lINF = 0x3f3f3f3f3f3f3f3f;
const int iINF = 0x3f3f3f3f;
inline ll read()
{
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = x * 10 + ch - '0', ch = getchar();
return x * f;
}
void solve()
{
ll l = q_;
ll r = q_;
//递归求解
ll base = l-1;
vector<ll>ans(r - base +1, 0);
ffp(i, 1, r - base)
{
ans[i] = i + base;
}
auto find = [&](auto&& find, ll L, ll R)->void
{
if (R <= L) { return; }
//查看va是否在L和R之内 数字为连续,即判断,当前位在L到R是否符合一半一半的特征
ll va = 0;
for (ll i = 32; i >= 0; i--)
{
ll b = 1ll << i;
if (((b & L) == 0) && ((b & R) != 0))
{
va |= b;
break;
}
if (((b & L) != 0) && ((b & R) != 0))
{
va |= b;
}
}
//查看左边和右边的数量
ll cnt = min(R - va + 1,va - L);
ffp(i, 1, cnt)
{
swap(ans[va - i - base] , ans[va + i - 1 - base]);
}
find(find, L, va - cnt - 1);
find(find, va + cnt, R);
};
find(find, l, r);
ll res = 0;
ffp(i, 1, r - l + 1)
{
res += (ans[i] | (i + base));
} cout << res << endl;
ffp(i, 1, r - l + 1)
{
cout << ans[i] << ' ';
}
cout << endl;
return;
}
int main()
{
int t = 1;
t = q_;
while (t--)
{
solve();
}
return 0;
}

浙公网安备 33010602011771号