题解:CF1777F Comfortably Numb / ARIS0_0 - 40
思路
方便讲述,我们设
我们对序列分治,对于一个分治区间
先处理右区间,从左往右枚举
我们就只需要找到一个范围内的
左区间同理,注意每处理一半区间后需清空字典树,算完答案继续递归左右区间即可。
时间复杂度
代码
#include<bits/stdc++.h>
#define cin_fast ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define fi first
#define se second
//#define int long long
#define in(a) a = read()
#define rep(i , a , b) for(int i = a ; i <= b ; i ++)
using namespace std;
typedef long long ll;
const int N = 2e5 + 5 , mod = 998244353;
const int inf = 0x3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
inline int read() {
int x = 0;
char ch = getchar();
bool f = 0;
while('9' < ch || ch < '0') f |= ch == '-' , ch = getchar();
while('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0' , ch = getchar();
return f ? -x : x;
}
int a[N] , trie[N * 30][2] , tot , w[N * 30];
void insert(int x) {
for(int i = 0 , j = 30 ; ~j ; j --) {
int pos = (x >> j) & 1;
if(!trie[i][pos]) trie[i][pos] = ++ tot;
i = trie[i][pos];
}
}
int query(int x) {
int ans = 0;
for(int i = 0 , j = 30 ; ~j ; j --) {
int pos = (x >> j) & 1;
if(trie[i][pos ^ 1]) ans |= (1 << j) , i = trie[i][pos ^ 1];
else i = trie[i][pos];
}
return ans;
}
void into() {
for(int i = 0 ; i <= tot ; i ++) trie[i][0] = trie[i][1] = 0;
tot = 0;
}
int ans;
void solve(int l , int r) {
if(l == r) return;
int mid = (l + r) >> 1;
into();
insert(0);
for(int i = mid + 1 , j = mid , maxx = 0 , x = 0, pre = a[mid] , prv = a[mid] ; i <= r ; i ++) {
maxx = max(maxx , a[i]);
x ^= a[i];
while(j >= l && prv <= maxx) {
insert(pre);
j --;
pre ^= a[j] , prv = max(prv , a[j]);
}
ans = max(ans , query(maxx ^ x));
}
solve(l , mid) , solve(mid + 1 , r);
into();
insert(0);
for(int i = mid , j = mid + 1 , maxx = 0 , x = 0 , pre = a[mid + 1] , prv = a[mid + 1] ; i >= l ; i --) {
maxx = max(maxx , a[i]);
x ^= a[i];
while(j <= r && prv <= maxx) {
insert(pre);
j ++;
pre ^= a[j] , prv = max(prv , a[j]);
}
ans = max(ans , query(maxx ^ x));
}
}
signed main() {
//cin_fast;
int t;
in(t);
while(t --) {
int n;
in(n);
int x = 0;
for(int i = 1 ; i <= n ; i ++) in(a[i]);
ans = 0;
solve(1 , n);
cout << ans << '\n';
}
return 0;
}
/*
破碎后失去光芒的我
心生被光拯救的梦
不愿放手 太多光芒照亮了我
才期待着守护着以后
重回那蔚蓝的天空
日升月落 我仍是我
this is ARIS 40
*/