博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BZOJ 3261]最大异或和
阅读量:5020 次
发布时间:2019-06-12

本文共 2683 字,大约阅读时间需要 8 分钟。

Description

给定一个初始长度为 \(N\) 的非负整数序列 \(\{A\}\) 。有 \(M\) 个操作,支持:

  1. \(A~x\) :添加操作,表示在序列末尾添加一个数 \(x\) ,序列的长度 \(N+1\)
  2. \(Q~l~r~x\) :询问操作,求 \[\max_{l\leq p\leq r}A_p\oplus A_{p+1}\oplus\cdots\oplus A_N\oplus x\]

\(1\leq N,M\leq 300000,0\leq A_i\leq 10^7\)

Solution

不妨记 \(A_i\) 的前缀异或和为 \(B_i\) ,显然题目转化为 \[\max_{l\leq p\leq r}B_{p-1}\oplus B_N\oplus x\]

我们不妨用类似主席树的思路,我们建一棵 \(B_i\)\(Trie\) ,并且将它持久化,然后贪心的选择。显然是可行的。

值得注意的是由于异或的前缀和,并且又因为差分,查询时的区间应该为 \([l-2,r-1]\) ,为了防止越界,可以先插入个 \(0\)\(Trie\)

Code

//It is made by Awson on 2018.3.16#include 
#define LL long long#define dob complex
#define Abs(a) ((a) < 0 ? (-(a)) : (a))#define Max(a, b) ((a) > (b) ? (a) : (b))#define Min(a, b) ((a) < (b) ? (a) : (b))#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))#define writeln(x) (write(x), putchar('\n'))#define lowbit(x) ((x)&(-(x)))using namespace std;const int N = 300000;void read(int &x) { char ch; bool flag = 0; for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar()); for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar()); x *= 1-2*flag;}void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }int n, m, bin[30], a, b, t, A[30], l, r; char ch[5];struct Trie { int root[(N<<1)+5], ch[N*50+5][2], key[N*50+5], pos; int cpynode(int o) {++pos; ch[pos][0] = ch[o][0], ch[pos][1] = ch[o][1], key[pos] = key[o]; return pos; } void insert(int &o, int *A) { int u = o = cpynode(o); ++key[u]; for (int i = 25; i >= 1; i--) { ch[u][A[i]] = cpynode(ch[u][A[i]]); u = ch[u][A[i]], ++key[u]; } } int query(int a, int b, int *A) { int ans = 0; for (int i = 25; i >= 1; i--) { if (key[ch[b][A[i]^1]]-key[ch[a][A[i]^1]] > 0) ans += bin[i-1], a = ch[a][A[i]^1], b = ch[b][A[i]^1]; else a = ch[a][A[i]], b = ch[b][A[i]]; } return ans; }}T;void work() { read(n), read(m); bin[0] = 1; for (int i = 1; i <= 25; i++) bin[i] = (bin[i-1]<<1); T.insert(T.root[1], A); ++n; for (int i = 2; i <= n; i++) { read(a), b ^= a, t = b; for (int j = 1; j <= 25; j++) A[j] = t%2, t /= 2; T.insert(T.root[i] = T.root[i-1], A); } while (m--) { scanf("%s", ch); if (ch[0] == 'A') { ++n; read(a), b ^= a, t = b; for (int j = 1; j <= 25; j++) A[j] = t%2, t /= 2; T.insert(T.root[n] = T.root[n-1], A); }else { read(l), read(r), read(t); t ^= b; for (int j = 1; j <= 25; j++) A[j] = t%2, t /= 2; writeln(T.query(T.root[l-1], T.root[r], A)); } }}int main() { work(); return 0;}

转载于:https://www.cnblogs.com/NaVi-Awson/p/8578413.html

你可能感兴趣的文章
Chromium多线程模型设计和实现分析
查看>>
JMS消息中间件原理及ActiveMQ用法
查看>>
2014记录+闲扯+总结-2015计划
查看>>
Cocos2d-x 3.2 大富翁游戏项目开发-第七部分 获取角色路径_2
查看>>
动态规划——递归写法和递推写法
查看>>
1006. 换个格式输出整数
查看>>
多行文字超出省略显示
查看>>
JS 打印实现部分打印
查看>>
python with语句
查看>>
[分 享] PHPCMS V9 更换域名,附件地址无法批更新(更换变便)问题>解决方法!!
查看>>
Android 开源UI组件使用(转载)
查看>>
EF6 的性能优化
查看>>
C# 多线程之Task资料
查看>>
jQuery $ 的作用
查看>>
Unity 用代码设置UGUI的渲染层级
查看>>
Js删除Table中的一行
查看>>
日记1
查看>>
VMware虚拟机下CentOS无法上网解决方法
查看>>
H3C 环路避免机制三:毒性逆转
查看>>
H3C NAT组网和常用术语
查看>>