#include<bits/stdc++.h>
using namespace std;
const int N = 100010*31;
int tr[N][2],cn[N],s[N];// trie节点有没有0/1儿子(路径序号),到达某一个节点的路径条数,前缀和数组
int idx;// 某一条路径的最后一个节点的索引
void insert(int u,int v){
int p = 0;//根节点
for(int i = 30;i>=0;i--){
int x = u>>i&1;
if(!tr[p][x]) tr[p][x] = ++idx;
p = tr[p][x];
cn[p]+=v;
}
}
int query(int x){
// 查询x与其中某个数的最大异或值
int p = 0,res = 0;
for(int i = 30;i>=0;i--){
int m = x>>i&1;
if(cn[tr[p][!m]]) {
p = tr[p][!m];
res = res * 2+ 1;
}
else{
p = tr[p][m];
res = res *2;
}
}
return res;
}
int main(){
int n,m;
cin>>n>>m;
// 先算前缀和
for(int i = 1;i<=n;i++){
int x;
cin>>x;
s[i] = s[i-1]^x;
}
insert(s[0],1);// 先插入s[0]
int res = 0;// 空数组异或值为0
//枚举n个数,求其滑动窗口中某个数与其最大异或值
for(int i = 1;i<=n;i++){
if(i-m-1>=0) insert(s[i-m-1],-1); // 删除s[i-m-1]
res = max(res,query(s[i]));
insert(s[i],1);
}
cout<<res;
}
字典树【最大异或和】
最新推荐文章于 2024-07-25 14:12:59 发布