当前位置: 首页 > news >正文

P4735 最大异或和 题解

P4735 最大异或和

题面:

题目描述

给定一个非负整数序列 { a } \{a\} {a},初始长度为 N N N

M M M 个操作,有以下两种操作类型:

  1. A x:添加操作,表示在序列末尾添加一个数 x x x,序列的长度 N N N 1 1 1
  2. Q l r x:询问操作,你需要找到一个位置 p p p,满足 l ≤ p ≤ r l \le p \le r lpr,使得: a [ p ] ⊕ a [ p + 1 ] ⊕ . . . ⊕ a [ N ] ⊕ x a[p] \oplus a[p+1] \oplus ... \oplus a[N] \oplus x a[p]a[p+1]...a[N]x 最大,输出最大值。
输入格式

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

输出格式

假设询问操作有 T T T 个,则输出应该有 T T T 行,每行一个整数表示询问的答案。

样例 #1
样例输入 #1
5 5
2 6 4 3 6
A 1 
Q 3 5 4 
A 4
Q 5 7 0 
Q 3 6 6
样例输出 #1
4
5
6
提示
  • 对于所有测试点, 1 ≤ N , M ≤ 3 × 1 0 5 1\le N,M \le 3\times 10 ^ 5 1N,M3×105 0 ≤ a i ≤ 1 0 7 0\leq a_i\leq 10 ^ 7 0ai107

首先,动态加数?平衡 trie?

显然不可做。

我们得考虑异或的性质——自反性!

转换一下题面: a [ p ] ⊕ a [ p + 1 ] ⊕ … ⊕ a [ N ] = ( ⊕ i = 1 N a [ i ] ) ⊕ ( ⊕ i = 1 p − 1 a [ i ] ) a[p] \oplus a[p+1] \oplus \ldots \oplus a[N] = (\oplus_{i = 1}^N a[i]) \oplus (\oplus_{i = 1}^{p - 1} a[i]) a[p]a[p+1]a[N]=(i=1Na[i])(i=1p1a[i])

( ⊕ i = 1 N a [ i ] ) (\oplus_{i = 1}^N a[i]) (i=1Na[i]),我们用一个全局tag就可以搞定。

( ⊕ i = 1 p − 1 a [ i ] ) (\oplus_{i = 1}^{p - 1} a[i]) (i=1p1a[i]),我们用 trie 来做定位。

其中 l ≤ p ≤ r l \leq p \leq r lpr,我们用 可持久化01-trie + 01-trie上二分 就可以解决!

AC-code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int rd() {int x = 0, w = 1;char ch = 0;while (ch < '0' || ch > '9') {if (ch == '-') w = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = x * 10 + (ch - '0');ch = getchar();}return x * w;
}
void wt(int x) {static int sta[35];int f = 1;if(x < 0) f = -1,x *= f;int top = 0;do {sta[top++] = x % 10, x /= 10;} while (x);if(f == -1) putchar('-');while (top) putchar(sta[--top] + 48);
}
const int N = 3e5+5; 
int rt[N << 2],n,m,a[N<<2];
namespace zo_trie{
int siz[N * 50],ls[N * 50],rs[N * 50],cnt;int update(int pr,int x,int dep) {int re = ++cnt;siz[re] = siz[pr] + 1;ls[re] = ls[pr];rs[re] = rs[pr];if(dep < 0) return re;((x >> dep) & 1) ? rs[re] = update(rs[pr],x,dep - 1) : ls[re] = update(ls[pr],x,dep - 1);return re;
}int query(int x,int y,int k,int dep){if(dep < 0) return 0;int lsz = siz[ls[y]] - siz[ls[x]];int rsz = siz[rs[y]] - siz[rs[x]];if((k >> dep) & 1) {if(lsz) return (int)(1<<(int)dep) + query(ls[x],ls[y],k,dep - 1);else return query(rs[x],rs[y],k,dep - 1);}else {if(rsz)return (int)(1<<(int)dep) + query(rs[x],rs[y],k,dep - 1);else return query(ls[x],ls[y],k,dep - 1);}
}}signed main() {n = rd(),m = rd();for(int i = 1;i<=n;i++) a[i] = rd();for(int i = 1;i<=n;i++) a[i] ^= a[i - 1];rt[0] = zo_trie::update(rt[0],0,25);for(int i = 1;i<=n;i++) rt[i] = zo_trie::update(rt[i - 1],a[i],25);while(m--) {char opt = getchar();while(opt != 'A' && opt != 'Q') opt = getchar();int A,B,C;switch(opt) {case 'A':A = rd();n++;a[n] = a[n - 1] ^ A;rt[n] = zo_trie::update(rt[n - 1],a[n],25);break;case 'Q':A = rd(),B = rd(),C = rd();A--,B--;C ^= a[n];if(A > 0) wt(zo_trie::query(rt[A - 1],rt[B],C,25));else wt(zo_trie::query(0,rt[B],C,25));putchar('\n');break;default:puts("Error");exit(0);break;}}return 0;
}

http://www.mrgr.cn/news/58172.html

相关文章:

  • 探索 JavaScript 事件机制(四):React 合成事件系统
  • K8S系列-Kubernetes网络
  • openrtp 音视频时间戳问题
  • OpenCV视觉分析之运动分析(2)背景减除类:BackgroundSubtractorKNN的使用
  • redis的配置文件解析
  • JavaWeb合集12-Redis
  • MES(制造执行系统)物料管理模块概述
  • Cursor零基础小白教程系列「高阶」 - Cursor 模型选择和API密钥配置
  • antv g6问题处理汇总
  • MySQL(python开发)——(10)Sql操作及优化
  • 智联引擎是什么?
  • 基于ssm+vue的房源管理系统设计与实现
  • 中国区 Microsoft365主页链接请您参考:
  • 时间数据可视化基础实验(大数据可视化)——Python热狗大胃王比赛前三名分析
  • xss-labs靶场第十二关测试报告
  • 程序员的最终出路在哪
  • ZYNQ AXI_GPIO_INT
  • 使用Python画一个蓝色的动感爱心
  • 升级到Delphi 12,DUnitx 测试用例项目闪退
  • C语言——求解一元二次方程
  • 【付费】Ambari集成Dolphin实战-004-实战bigtop.bom——下
  • 网易博客旧文----BASE64编码解码工具的使用
  • Jenkins + GitLab + Docker实现自动化部署(Java项目)
  • 基于ssm+jsp的宠物常规护理知识管理系统设计与实现(含源码+数据库)
  • Strategy_Mode
  • vue中使用 html2canvas绘制图片并下载