Equalization
无敌 brute force。注意到 约为 ,,大胆猜测仅需要 以内的数就够了。使用复杂度为 的子集枚举算法枚举所有分配的方案,足以填满整个数组。对于每次询问枚举要右移多少位,取个 min 就好了。
#include <array>
#include <bit>
#include <iostream>
#include <limits>
#include <utility>
using namespace std;
istream& fin = cin;
ostream& fout = cout;
using ui = unsigned int;
using uli = unsigned long long int;
using li = long long int;
const auto f = []() {
array<array<ui, 64>, 64> d;
for (auto& i : d)
for (auto& j : i) j = numeric_limits<ui>::max();
for (ui i = 0; i < (1u << 16); ++i)
for (ui j = i; j; j = i & (j - 1)) {
ui x = 0, y = 0;
for (ui k = 0; k < 16; ++k)
if ((i >> k) & 1) ((j >> k) & 1 ? x : y) += k + 1;
if (x < 64 && y < 64) d[x][y] = d[y][x] = min(d[x][y], i);
}
return d;
}();
int main(void) {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
size_t T;
fin >> T;
while (T--) {
uli x, y;
fin >> x >> y;
if (x == y) {
fout << "0\n";
continue;
}
if (x < y) swap(x, y);
ui ans = numeric_limits<ui>::max();
for (ui i = 0; i < 58; ++i)
for (ui j = 0; j < 58; ++j)
if ((x >> i) == (y >> j)) { ans = min(ans, f[i][j]); }
fout << ans * 2 << '\n';
}
return 0;
}