区间异或和异或区间最大值异或区间最小值

区间异或和异或区间最大值异或区间最小值

关键

分治思想。
也可以选择固定左端点,然后选择右端点

代码

#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int M=1e5+5;
int ch[M*32][2],cnt[M*32],tot;
void init() {
for(int i=0;i<=tot;i++)
cnt[i]=ch[i][0]=ch[i][1]=0;
tot=0;
}
void insert(int x) {
int p=0;
for(int i=30;i>=0;i--) {
int v=x>>i&1;
if(ch[p][v]==0)ch[p][v]=++tot;
p=ch[p][v];
cnt[p]++;
}
}
void del(int x) {
int p=0;
for(int i=30;i>=0;i--) {
int v=x>>i&1;
p=ch[p][v];
cnt[p]--;
}
}
int ans;
void query(int x) {
int p=0,res=0;
for(int i=30;i>=0;i--) {
int v=x>>i&1;
if(cnt[ch[p][v^1]])res|=1<<i,p=ch[p][v^1];
else p=ch[p][v];
}
ans=max(ans,res);
}
int a[M],b[M],sum[M];
void solve(int l,int r) {
if(l==r)return ;
int mid=(l+r)/2;
solve(l,mid);
solve(mid+1,r);
b[mid]=sum[mid]=0;
for(int i=mid+1;i<=r;i++)b[i]=max(b[i-1],a[i]),sum[i]=sum[i-1]^a[i];
{
init();
int rp=mid;
int mx=0,mn=inf,tmp=0;
for(int i=mid;i>=l;i--) {
mx=max(mx,a[i]);
mn=min(mn,a[i]);
tmp^=a[i];
while(rp<r&&a[rp+1]<=mx&&a[rp+1]>=mn)insert(sum[++rp]);//最大值和最小值都在左边
query(tmp^mx^mn);
}
{
init();
int lp=mid+1,rp=mid;
int mx=0,mn=inf,tmp=0;
for(int i=mid;i>=l;i--) {
mx=max(mx,a[i]);
mn=min(mn,a[i]);
tmp^=a[i];
while(rp<r&&a[rp+1]>=mn)insert(sum[rp+1]^b[rp+1]),rp++;//
while(lp<=rp&&b[lp]<mx)del(sum[lp]^b[lp]),lp++;
query(mn^tmp);//最小值在左边
}
}
}
}
int main() {
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],ans=max(ans,a[i]);
solve(1,n);
reverse(a+1,a+1+n);
solve(1,n);
cout<<ans;
return 0;
}
//分治的思想,不是很懂呀
posted @   basicecho  阅读(133)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示