Loading

CF1732C2 Sheikh (Hard Version)

CF1732C2 Sheikh (Hard Version)

如果知道一个关键性质,\(a-b\le a\oplus b\le a+b\)

那么可以证得,从当前区间一端拓展一个数 \(b\)\((x+b)-(y\oplus b)\ge (x+b)-(y+b)=x-y\),这意味着区间越大,答案不会更劣。

那么很多需要考虑的东西都没了,只需要找到一个区间 \(L\le l\le r\le R\),满足 \(f(l,r)=f(L,R)\)

考虑看成从两端删数,于是 \((x-\sum x)-(y\oplus \bigoplus x)\le (x-\sum x)-(y-\bigoplus x)=x-y-(\sum x-\bigoplus x)\),等号成立的必要条件为 \(\sum x=\bigoplus x\)。(并且 \(y-\sum x=y\oplus\bigoplus x\) )

意味着各个二进制至多只有一个 \(1\),看数据范围,所以最多删 \(30\) 个数。

需要注意的是,\(0\) 需要删去,否则删去的数会多于 \(30\),导致 TLE。

debug 半天,一定要注意离散化后只有大小关系,所以长度需要一直判断,不能 break。

#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define fi first
#define se second
#define mk std::make_pair
#define pb push_back

using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;

const int N = 2e5 + 10;
i64 t;
i64 n, q, a[N], b[N], cnt;
i64 s1[N], s2[N];
void solve() {
	cnt = 0;
	std::cin >> n >> q;
	for(int i = 1; i <= n; i++) std::cin >> a[i];

	for(int i = 1; i <= n; i++) {
		if(a[i]) b[++cnt] = i;
	}

	for(int i = 1; i <= cnt; i++) s1[i] = s1[i - 1] + a[b[i]], s2[i] = s2[i - 1] ^ a[b[i]];

	while(q--) {
		int l, r;
		std::cin >> l >> r;
		int L = std::lower_bound(b + 1, b + cnt + 1, l) - b, R = std::upper_bound(b + 1, b + cnt + 1, r) - b - 1;
		i64 ret = s1[R] - s1[L - 1] - (s2[R] ^ s2[L - 1]); 
		if(L > R || !cnt) {
			std::cout << l << " " << l << "\n";
			continue;
		} 
		int ansl = b[L], ansr = b[R];
		// std::cout << L << " " << R << "\n";
		for(int i = std::min(R - L, 60); i >= 1; i--) {
			for(int j = 0; j <= i; j++) {
				i64 sum = s1[R - (i - j)] - s1[L + j - 1] - (s2[R - (i - j)] ^ s2[L + j - 1]);
				// std::cout << L + j << " " << R - (i - j) << " " << sum << " " << ret << "\n";
				if(sum == ret && ansr - ansl > b[R - (i - j)] - b[L + j]) {
					ansl = b[L + j], ansr = b[R - (i - j)];
                    // break; 不能写
				}
			}
			// if(ansl != b[L] || ansr != b[R]) break; 不能写
		}
		std::cout << ansl << " " << ansr << "\n";
	}
}
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	
	std::cin >> t;

	while(t--) solve();

	return 0;
}
posted @ 2024-10-16 08:31  Fire_Raku  阅读(2)  评论(0编辑  收藏  举报