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;
}