1951. 宇宙人浇花(最大异或对变形)

https://citel.bjtu.edu.cn/acm/problem/1951#submit

  1. 宇宙人浇花
    时间限制 1000 ms   内存限制 256 MB
    因为没见过飞船,则卷博士把宇宙人的飞船修成了小汽车,于是他们被迫留在了企鹅村。
    失去目标的宇宙人没有变成咸鱼,他们很快找到了一份浇花的工作。
    花园的花一字排开,每盆花都有一个美丽值,而整个花园的和谐度是所有花美丽值的异或和。
    宇宙人只能浇连续的一段花,并且一天只能浇一次,每盆被浇到的花美丽值都会加 1。
    花园主人琪琪想让今天花园的和谐度尽可能大,请问和谐度最大能达到多少?(如果浇水不能增大花园的和谐度,宇宙人可以不浇水)

输入数据
第一行是一个整数 n (1≤n≤10^5) ,表示花的盆数。
第二行是 n 个整数 a1,a2,…,an (1≤ai≤10^9) ,表示n盆花的美丽值。

输出数据
输出一个整数,即花园今天能达到的最大和谐度。

样例输入
5
4 5 2 3 1
样例输出
7
样例说明
宇宙人可以浇第 3 盆和第 4 盆花,浇完花后,这些花的美丽值变为 4 5 3 4 1 ,4⊕5⊕3⊕4⊕1=7 ,可以证明 7 是能得到的最大和谐度。

思路:

  • 一段的连续异或可以用前缀异或来处理
  • 对于连续修改,需要预处理前缀异或没有加的和加了的然后扔到字典树上去。
  • 查询的时候查询a[i]^b[i]类似于把当前连续增加的一段先和b[i]抵消成0,然后再把a[i]给加回上去。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+1000;
typedef long long LL;
inline LL read(){
    
    LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){
    
    if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){
    
    x=x*10+ch-48;ch=getchar();}
return x*f;}
LL tree[maxn][2],a[maxn],prea[maxn],preb[maxn],pt=0;
void ins(LL val){
    
    
     LL cur=0;
     for(LL i=31;i>=0;i--){
    
    
         LL c=(val>>i)&1;
         if(!tree[cur][c]) tree[cur][c]=++pt;
         cur=tree[cur][c];
     }
}
LL query(LL val){
    
    
    LL res=0;LL cur=0;
    for(LL i=31;i>=0;i--){
    
    
        LL c=(val>>i)&1;
        if(tree[cur][1^c]) {
    
    
            res+=1LL<<i;
            cur=tree[cur][1^c];
        }
        else{
    
    
            res+=0;
            cur=tree[cur][c];
        }
    }
    return res;
}
int main(void){
    
    
   	cin.tie(0);std::ios::sync_with_stdio(false);
    LL n;cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++){
    
    
        prea[i]=prea[i-1]^a[i];
        preb[i]=preb[i-1]^(a[i]+1);
    }
    LL ans=0;
    for(int i=1;i<=n;i++){
    
    
        LL x=(prea[n]^prea[i])^preb[i];
        ins(x);
        ans=max(ans,query(prea[i]^preb[i]));
    }
    cout<<ans<<endl;
   	return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/121183488