宇宙人浇花(异或前缀和+trie+思维,最大异或对问题)

简介: 宇宙人浇花(异或前缀和+trie+思维,最大异或对问题)

题目传送门

1.题目大意:

a序列的n个数异或和为:a 1 a1a1 xor a 2 a2a2 xor a 3 a3a3 xor a 4 a4a4…xor a n anan

可以对一段连续的a l . . a r al..aral..ar加一,操作一次或者不操作,求操作之后的n个数的异或和

2.分析题目:

最后一定是前面一部分不加一,中间一部分加一,后面一部分不加一,注意每部分可能长度为0

维护两个前缀数组:

1.b [ i ] 维 护 前 i 个 a [ i ] + 1 的 异 或 和 b[i]维护前i个a[i]+1的异或和b[i]ia[i]+1

2.a [ i ] 维 护 前 i 个 a [ i ] 的 异 或 和 a[i]维护前i个a[i]的异或和a[i]ia[i]

3.再用字典树维护a[n] ^ a[i] ^ b[i]

为什么要字典树维护a[n]^a[i] ^b[i]呢?

想想,首先异或运算是满足交换律和结合律的

因为a [ i ] a[i]a[i]维护的是原a数组的前缀异或和,a[i]^a[n]剩下的是原a数组的,a[i+1] ^ a[i+2]a[n]

b[i] ^ a[i] ^ a[n]为 原a数组的前i个(a[i]+1)异或和再异或原 数组的后面的n-i个a[i]的异或和

(a[1]+1) ^ (a[2]+1) ^(a[3]+1) ^ … ^(a[i]+1) ^a[i+1] ^a[i+2] ^… ^ a[n]

遍历一遍将所有的a[i]^a[n] ^b[i]放trie上面

4.再用a[i]^b[i]去查询trie上的最大异或对

为什么是a[i]^b[i]去查询呢?

因为答案一定是某一个 a[x] ^ b[x] ^ (a[n] ^ a[i] ^ b[i])

简单证明一下:

通过3已知,(a[n] ^ a[i] ^ b[i])为:

(a[1]+1) ^ (a[2]+1) ^(a[3]+1) ^ … ^(a[i]+1) ^a[i+1] ^a[i+2] ^… ^ a[n]

(这里的a数组是没有前缀处理的原a数组)

此时a[n] ^ a[i] ^ b[i]再异或b[x]^a[x]

就会将索引为1-x的异或变成0((a[i]+1)^(a[i]+1)),再将索引1-x的异或和变成a[1] ^ a[2] a[x]

整个a[x] ^ b[x] ^ (a[n] ^ a[i] ^ b[i])变成:

a[1] ^ a[2] ^ …^ a[x] ^ (a[x+1]+1) ^ (a[x+1]+1) ^ (a[x+2]+1) (a[x+k]+1) ^ a[x+k+1] ^ …a[n]

分成开始说的三段!

接下来就是求最大异或对了!

代码:

#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
# define rep(i,be,en) for(int i=be;i<=en;i++)
# define pre(i,be,en) for(int i=be;i>=en;i--)
typedef pair<int, int> PII;
#define ll long long
#define endl "\n"
#define LOCAL
#define pb push_back
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
inline int read()
{
  int X = 0;
  bool flag = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') flag = 0;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    X = (X << 1) + (X << 3) + ch - '0';
    ch = getchar();
  }
  if (flag) return X;
  return ~(X - 1);
}
inline void write(int X)
{
  if (X < 0) {
    X = ~(X - 1);
    putchar('-');
  }
  if (X > 9) write(X / 10);
  putchar(X % 10 + '0');
}
int son[N][3];
int n;
int idx, a[N], b[N];
void insert(int x)
{
  int p = 0, u;
  for (int i = 31; i >= 0; i--)
  {
    u = (x >> i) & 1;
    if (!son[p][u]) son[p][u] = ++idx;
    p = son[p][u];
  }
}
int query(int x)
{
  int p = 0, u;
  int res = 0;
  for (int i = 31; i >= 0; i--)
  {
    u = (x >> i) & 1;
    if (son[p][u ^ 1]) res += 1 << i, p = son[p][u ^ 1];
    else
      p = son[p][u];
  }
  return res;
}
void solve()
{
  n = read();
  rep(i, 1, n)
  {
    a[i] = read();
    b[i] = a[i] + 1;
  }
  for (int i = 1; i <= n; i++)
  {
    a[i] ^= a[i - 1];
    b[i] ^= b[i - 1];
  }
  for (int i = 0; i <= n; i++)
  {
    int x = a[n] ^ a[i] ^ b[i];
    insert(x);
  }
  int ans = 0;
  for (int i = 0; i <= n; i++)
    ans = max(ans, query(b[i] ^ a[i]));
  cout << ans << "\n";
}
int main() {
  ios::sync_with_stdio;
  cin.tie(0);
  cout.tie(0);
  //#ifdef LOCAL
  //freopen("data.in.txt","r",stdin);
  //freopen("data.out.txt","w",stdout);
  //#endif
  int T = 1;
  //scanf("%d",&T);
  while (T--)
  {
    solve();
  }
  return 0;
}

撰文不易,点个赞再走吧!

目录
相关文章
|
机器学习/深度学习 算法 Serverless
大模型开发:描述损失函数的作用以及一些常见的损失函数。
损失函数在机器学习中至关重要,用于衡量预测误差、优化模型、评估性能及选择模型。常见类型包括均方误差(MSE)、均方根误差(RMSE)、交叉熵损失(适用于分类)、绝对误差(MAE)、hinge损失(SVMs)、0-1损失、对数似然损失和Focal Loss(应对类别不平衡)。选择时要考虑模型性质、数据特征和优化需求。
1409 3
Pyside6-第四篇-QCheckBox复选框
Pyside6-第四篇-QCheckBox复选框
1434 0
Pyside6-第四篇-QCheckBox复选框
|
前端开发 JavaScript 关系型数据库
前后端分离 -- SpringBoot + Vue实战项目 部署至阿里云服务器
前后端分离 -- SpringBoot + Vue实战项目 部署至阿里云服务器
4058 2
前后端分离 -- SpringBoot + Vue实战项目 部署至阿里云服务器
|
XML Java 数据库连接
性能提升秘籍:如何高效使用Java连接池管理数据库连接
在Java应用中,数据库连接管理至关重要。随着访问量增加,频繁创建和关闭连接会影响性能。为此,Java连接池技术应运而生,如HikariCP。本文通过代码示例介绍如何引入HikariCP依赖、配置连接池参数及使用连接池高效管理数据库连接,提升系统性能。
242 5
|
11月前
|
机器学习/深度学习 资源调度 计算机视觉
RT-DETR改进策略【Conv和Transformer】| CVPR-2022 Deformable Attention Transformer 可变形注意力 动态关注目标区域
RT-DETR改进策略【Conv和Transformer】| CVPR-2022 Deformable Attention Transformer 可变形注意力 动态关注目标区域
528 15
RT-DETR改进策略【Conv和Transformer】| CVPR-2022 Deformable Attention Transformer 可变形注意力 动态关注目标区域
|
11月前
|
人工智能 计算机视觉
RT-DETR改进策略【损失函数篇】| NWD损失函数,提高小目标检测精度
RT-DETR改进策略【损失函数篇】| NWD损失函数,提高小目标检测精度
907 5
RT-DETR改进策略【损失函数篇】| NWD损失函数,提高小目标检测精度
|
安全 Java 程序员
【多线程-从零开始-肆】线程安全、加锁和死锁
【多线程-从零开始-肆】线程安全、加锁和死锁
259 0
|
机器学习/深度学习 自然语言处理 搜索推荐
探索深度学习中的注意力机制及其在现代应用中的影响
探索深度学习中的注意力机制及其在现代应用中的影响
398 1
|
存储 人工智能 缓存
AI助理直击要害,从繁复中提炼精华——使用CDN加速访问OSS存储的图片
本案例介绍如何利用AI助理快速实现OSS存储的图片接入CDN,以加速图片访问。通过AI助理提炼关键操作步骤,避免在复杂文档中寻找解决方案。主要步骤包括开通CDN、添加加速域名、配置CNAME等。实测显示,接入CDN后图片加载时间显著缩短,验证了加速效果。此方法大幅提高了操作效率,降低了学习成本。
5918 16
|
存储 安全 Java
Hashtable 和 HashMap 的区别
【8月更文挑战第22天】
1254 0