题目:
给定一个非负整数数列 a,初始长度为 N。
请在所有长度不超过 M 的连续子数组中,找出子数组异或和的最大值。
子数组的异或和即为子数组中所有元素按位异或得到的结果。
注意:子数组可以为空。
输入格式
第一行包含两个整数 N,M。
第二行包含 N 个整数,其中第 i 个为 ai。
输出格式
输出可以得到的子数组异或和的最大值。
数据范围
对于 20% 的数据,1≤M≤N≤100
对于 50% 的数据,1≤M≤N≤1000
对于 100% 的数据,1≤M≤N≤105,0≤ai≤231−1
本题的关键 是trie 树的建立与删除。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e5+10, M = 31*N;
int n,m;
int son[M][2],idx;
int s[N];
int cnt[M];
void insert(int x,int v)
{
int p = 0;
for(int i = 30;i>=0;i--)
{
int u = x>>i&1;
if(!son[p][u]) son[p][u] = ++idx;
p = son[p][u];
cnt[p]+=v;//记录能到这个节点的前缀和个数
}
}
int query(int x)
{
int p = 0,res =0;
for(int i = 30; i>=0;i--)
{
int u = x>>i&1;
if(cnt[son[p][!u]])
{
p = son[p][!u];
res = res*2+!u;
}
else
{
p = son[p][u];
res = res*2+u;
}
}
return res;
}
int main()
{
scanf("%d%d",&n,&m);
int res = 0;
for(int i = 1; i<=n;i++)
{
int x;
scanf("%d",&x);
s[i] = s[i-1]^x;
if(i>1)
{
if(i>m+1) insert(s[i-m-1],-1);
int t = query(s[i]);
res = max(res,s[i]^t);
if(i<=m) res= max(res,s[i]);
}
insert(s[i],1);
}
cout<<res<<endl;
return 0;
}
标签:最大,trie,res,son,int,异或,数组
From: https://www.cnblogs.com/freshman666/p/17174366.html