CF E求调
  • 板块学术版
  • 楼主lalaouye
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/3/6 00:41
  • 上次更新2024/3/6 15:45:14
查看原帖
CF E求调
431289
lalaouye楼主2024/3/6 00:41

贪心思路,先处理肯定有 11 的位,然后如果找到第一个 x,yx,y 不同的位,它一共有两种可能,一种是舍弃这一位后面全 11,一种是这一位选 11 然后后面的数插进优先队列,一共只可能有 3030 个数,再暴力处理这不到 3030 个的数。调了蛮久了,自闭了,求大佬帮助。

#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 ();
}  

2024/3/6 00:41
加载中...