贪心思路,先处理肯定有 1 的位,然后如果找到第一个 x,y 不同的位,它一共有两种可能,一种是舍弃这一位后面全 1,一种是这一位选 1 然后后面的数插进优先队列,一共只可能有 30 个数,再暴力处理这不到 30 个的数。调了蛮久了,自闭了,求大佬帮助。
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l; i <= r; ++ i)
#define rrp(i, l, r) for (int i = r; i >= l; -- i)
#define int long long
#define eb emplace_back
#define ls (p << 1)
#define rs (ls | 1)
#define pii pair<int, int>
#define inf 2000000000
#define linf 10000000000000000
#define x first
#define y second
using namespace std;
constexpr int P = 998244353, N = 2e5 + 5;
inline int rd ()
{
int x = 0, f = 1;
char ch = getchar ();
while (! isdigit (ch)) { if (ch == '-') f = -1; ch = getchar (); }
while (isdigit (ch)) { x = (x << 1) + (x << 3) + ch - 48; ch = getchar (); }
return x * f;
}
int n, m;
int x[N], y[N];
int sum[N][31], s[N][31];
vector <int> vec[31], ve;
void solve ()
{
n = rd ();
rep (i, 1, n) x[i] = rd (), y[i] = rd ();
rep (i, 1, n) rep (j, 0, 30) sum[i][j] = s[i][j] = 0;
rep (i, 0, 30) vec[i].clear ();
rep (i, 1, n)
{
rrp (j, 0, 30)
{
if ((x[i] >> j & 1) != (y[i] >> j & 1))
{
vec[j].eb (i); ++ s[i][j];
break;
} else if (x[i] >> j & 1) ++ sum[i][j];
}
}
rep (i, 1, n) rep (j, 0, 30) sum[i][j] += sum[i - 1][j], s[i][j] += s[i - 1][j];
int T = rd ();
priority_queue <int> q;
while (T --)
{
ve.clear ();
int l = rd (), r = rd ();
int ret = 0;
rep (i, 0, 30) if (sum[r][i] - sum[l - 1][i] > 0) ret |= 1 << i;
rrp (i, 0, 30)
{
if (s[r][i] - s[l - 1][i] > 1)
{
ret |= (1ll << (i + 1)) - 1;
}
if (s[r][i] - s[l - 1][i] == 1)
{
if (ret >> i & 1)
{
ret |= (1 << i) - 1;
continue;
}
ret |= 1 << i;
int L = 0, R = vec[i].size () - 1, x;
while (L <= R)
{
int mid = L + R >> 1;
if (vec[i][mid] >= l)
{
x = y[vec[i][mid]];
R = mid - 1;
} else L = mid + 1;
}
if (x > (1 << i)) q.push (x - (1 << i));
}
} //cout<<ret<<" ";
while (! q.empty ())
{
int x = q.top ();
q.pop ();
int t;
rrp (i, 0, 30) if (x >> i & 1)
{
t = i; break;
}
if (ret >> t & 1)
{
ret |= (1 << t) - 1;
break;
} else
{
ret |= 1 << t;
if (x > (1 << t))
q.push (x ^ (1 << t));
}
}
while (! q.empty ()) q.pop ();
printf ("%lld ", ret);
} puts ("");
}
signed main ()
{
// freopen ("1.in", "r", stdin);
// freopen ("1.out", "w", stdout);
int T = rd ();
while (T --) solve ();
}