BZOJ4260 Codechef REBXOR【01字典树】

2024-01-20 14:38

本文主要是介绍BZOJ4260 Codechef REBXOR【01字典树】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

4260: Codechef REBXOR

https://www.lydsy.com/JudgeOnline/problem.php?id=4260

时间限制: 10 Sec  内存限制: 256 MB

 

题目描述

 

输入

输入数据的第一行包含一个整数N,表示数组中的元素个数。

第二行包含N个整数A1,A2,…,AN。

 

输出

输出一行包含给定表达式可能的最大值。

 

样例输入

5
1 2 3 1 2

样例输出

6

提示

满足条件的(l1,r1,l2,r2)有:(1,2,3,3),(1,2,4,5),(3,3,4,5)。

对于100%的数据,2 ≤ N ≤ 4*10^5,0 ≤ Ai ≤ 10^9。

思路

先说明几个数组的作用

a[]存放原数组

pre[]存放异或前缀

suf[]存放异或后缀

dp[i]存放前i个数中任意区间异或的最大值

 

求两个不相交的区间,两区间异或后的和最大,设第二个区间的左端点为m,则第一个区间在[1,m-1)内,第二个区间的左端点为m,右端点在[m,n]内,其中n表示数的个数,我们枚举m,即m取值为[2,n], 在m确定的情况下求最大的值,当两个数分别取最大时,它们的和最大,此时dp[]就排上用处了,在m确定的情况下,第一个区间的最大异或值为dp[m-1](即前m-1个数中任意区间异或的最大值)。

 

如何求以元素a[i]为结束元素的区间的异或最大值?由于异或操作有这么个性质

异或前缀: pre[i]^pre[j]=a[i+1]^a[i+2]^...^a[j] (i<j)

异或后缀:suf[i]^suf[j]=a[i]^a[i+1]^...^a[j-1] (i<j)

我们求以元素a[i]为结束元素的区间的异或最大值,使用异或前缀pre[],我们将per[0],pre[1],..,pre[i-1]插入到01字典树中,然后查找与a[i]以后后值最大的数即可。同理可使用异或后缀suf[] 求以元素a[i]为开始元素的区间的异或最大值。

 

通过上面的分析,这道问题就好解决了,先用pre[]和01字典树求出dp[],然后枚举第二个区间的左端点m,求第二个区间的异或最大值就是求以a[m]为开始元素的区间的异或最大值,使用01字典树即可。

C++代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>using namespace std;const int N=400500;int a[N],trie[32*N][2],dp[N],pre[N],suf[N];
int tot;//插入操作 
void insert(int x)
{int rt=0;for(int i=31;i>=0;i--){int c=(x>>i)&1;if(!trie[rt][c]) trie[rt][c]=++tot;rt=trie[rt][c];}
}//查询操作 
int query(int x)
{int rt=0,m=0;for(int i=31;i>=0;i--){int c=(x>>i)&1;if(trie[rt][c^1]){m=((c^1)<<i)|m;rt=trie[rt][c^1];}else{m=(c<<i)|m;rt=trie[rt][c];}}return m^x;
}int main()
{int n;while(~scanf("%d",&n)){memset(dp,0,sizeof(dp));memset(pre,0,sizeof(pre));memset(suf,0,sizeof(suf));memset(trie,0,sizeof(trie));tot=0;for(int i=1;i<=n;i++) scanf("%d",&a[i]);//输入原数组 for(int i=1;i<=n;i++) pre[i]=a[i]^pre[i-1];//求前缀  for(int i=n;i>=1;i--) suf[i]=a[i]^suf[i+1];//求后缀//插入pre[0]即0,通过pre[]和01字典树求dp[] insert(0);for(int i=1;i<=n;i++){dp[i]=max(query(pre[i]),dp[i-1]);insert(pre[i]);} int ans=0;//初始化01字典树 tot=0;memset(trie,0,sizeof(trie));insert(0);for(int i=n;i>=1;i--){ans=max(ans,dp[i-1]+query(suf[i]));insert(suf[i]);}printf("%d\n",ans);}return 0;
} 

 

这篇关于BZOJ4260 Codechef REBXOR【01字典树】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/626336

相关文章

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

POJ2001字典树

给出n个单词,求出每个单词的非公共前缀,如果没有,则输出自己。 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;

集中式版本控制与分布式版本控制——Git 学习笔记01

什么是版本控制 如果你用 Microsoft Word 写过东西,那你八成会有这样的经历: 想删除一段文字,又怕将来这段文字有用,怎么办呢?有一个办法,先把当前文件“另存为”一个文件,然后继续改,改到某个程度,再“另存为”一个文件。就这样改着、存着……最后你的 Word 文档变成了这样: 过了几天,你想找回被删除的文字,但是已经记不清保存在哪个文件了,只能挨个去找。真麻烦,眼睛都花了。看

01 Docker概念和部署

目录 1.1 Docker 概述 1.1.1 Docker 的优势 1.1.2 镜像 1.1.3 容器 1.1.4 仓库 1.2 安装 Docker 1.2.1 配置和安装依赖环境 1.3镜像操作 1.3.1 搜索镜像 1.3.2 获取镜像 1.3.3 查看镜像 1.3.4 给镜像重命名 1.3.5 存储,载入镜像和删除镜像 1.4 Doecker容器操作 1.4

python 实现第k个字典排列算法

第k个字典排列算法介绍 "第k个字典排列"算法通常指的是在给定的字符集合(例如,字符串中的字符)中,找到所有可能排列的第k个排列。这个问题可以通过多种方法解决,但一个常见且高效的方法是使用“下一个排列”算法的变种,或称为“第k个排列”的直接算法。 方法一:使用“下一个排列”的变种 生成所有排列:首先生成所有排列,但显然这种方法对于较大的输入集合是不切实际的,因为它涉及到大量的计算和存储。 排序

滚雪球学MyBatis(01):教程导读

MyBatis简介 前言 欢迎回到我们的MyBatis系列教程。在上期的内容中,我们详细介绍了MyBatis的基本概念、特点以及它与其他ORM框架(如Hibernate)的对比。我们还探讨了MyBatis在数据访问层中的优势,并解释了为什么选择MyBatis作为我们的持久化框架。在阅读了上期的内容后,相信大家对MyBatis有了初步的了解。 在本期内容中,我们将深入探讨MyBatis的基本配

POJ3617(字典序最小问题)

书中43页 此题有坑点,PE了40分钟.也是醉了....题目要求每80个字符才换行,而且最后一个如果恰好就不用换,这不是无聊嘛....... #include <iostream>#include <cstdio>#include <cstring>using namespace std;int n,m;char S[2100],P[2100];int main(){#ifd

POJ 2001 Shortest Prefixes(字典树入门)

题目: http://poj.org/problem?id=2001 题意: 找到多个字符串中,各自唯一的最短子串,例如 carte 与 carce 各自唯一的最短子串为cart与carc,即不会与其它字符串的子串重复。 思路: 字典树 解题心得: 更新关键值的时机很重要 代码: #include<stdio.h>#include<string>typedef str

python+selenium2轻量级框架设计-01框架结构

接下来会介绍一个比较简单的框架结构,先看一下分类 config文件夹里放的是配置文件 framework文件夹里面放的是公共类,常用类,还有读配置文件类、日志类、截图类、发送邮件、生成测试报告、操作读取数据库、读取Excel等,后面几篇会一一介绍 logs文件夹存放生成的日志文件 pageobject存放页面类包括元素的定位等 screenshots文件放的是生成的截图 test_

python+selenium2学习笔记POM设计模式-01模式简介

Page Object模式是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题 等),这样在Selenium测试页面中可以通过调用页面类来获取页面元素,这样巧妙的避免了当页面元素id或者位置变化时,需要改测试页面代码的情况。 当页面元素id变化时,只需要更改测试页Class中页面的属性即可。 Page Object模式是