BZOJ 3261: 最大异或和

Description

给定一个非负整数序列 a {a} a,初始长度为 N N N
M M M个操作,有以下两种操作类型:
1、 A x A x Ax :添加操作,表示在序列末尾添加一个数x,序列的长度N+1。
2、 Q l r x Q l r x Qlrx :询问操作,你需要找到一个位置 p p p,满足 l < = p < = r l<=p<=r l<=p<=r,使得:
a [ p ] a[p] a[p] x o r xor xor a [ p + 1 ] a[p+1] a[p+1] x o r xor xor . . . ... ... x o r xor xor a [ N ] a[N] a[N] x o r xor xor x x x 最大,输出最大是多少。

Input

第一行包含两个整数 N N N M M M,含义如问题描述所示。
第二行包含 N N N个非负整数,表示初始的序列 A A A
接下来 M M M行,每行描述一个操作,格式如题面所述

题解:

可持久化 T r i e Trie Trie

这个题我们维护前缀异或值,因为要加入新的值在后面。

然后对于每个前缀异或值,都建一个 T r i e Trie Trie树,最后询问的时候在 l l l r r r区间中取数,因为要异或 x x x最大,所以我们贪心走当前二进制位的反向边即可。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e7+50;
int tot,n,m,root[MAXN],a[MAXN];
int cnt[MAXN],nxt[MAXN][2];
inline void Insert(int idx,int x){
    int pre = root[idx-1],now = ++tot;
    root[idx] = now;
    for(int i=23;i>=0;i--){
        int k = (x>>i)&1;
        cnt[now] = cnt[pre] + 1;
        nxt[now][k^1] = nxt[pre][k^1];
        nxt[now][k] = ++tot;
        now = nxt[now][k];
        pre = nxt[pre][k];
    }
    cnt[now] = cnt[pre] + 1;
}
inline int Query(int l,int r,int x){
    int ll = root[l],rr = root[r],res = 0;
    for(int i=23;i>=0;i--){
        int k = (x>>i)&1;
        if(cnt[nxt[rr][k^1]]-cnt[nxt[ll][k^1]]) res += 1<<i,k^=1;
        ll = nxt[ll][k];
        rr = nxt[rr][k];
    }
    return res;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    Insert(1,0);
    for(int i=1;i<=n;i++) a[i]^=a[i-1],Insert(i+1,a[i]);
    while(m--){
        char op; int l,r,x;
        scanf(" %c",&op);
        if(op=='A'){
            scanf("%d",&x);
            a[++n] = a[n-1]^x;
            Insert(n+1,a[n]);
        }
        else {
            scanf("%d%d%d",&l,&r,&x);
            printf("%d\n",Query(l-1,r,a[n]^x));
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值