题目描述

Welcome to ALO ( Arithmetic and Logistic Online)。这是一个VR MMORPG ,如名字所见,到处充满了数学的谜题。
现在你拥有n颗宝石,每颗宝石有一个能量密度,记为ai,这些宝石的能量密度两两不同。现在你可以选取连续的一些宝石(必须多于一个)进行融合,设为  ai, ai+1, …, a j,则融合而成的宝石的能量密度为这些宝石中能量密度的次大值与其他任意一颗宝石的能量密度按位异或的值,即,设该段宝石能量密度次大值为k,则生成的宝石的能量密度为max{k xor ap | ap ≠ k , i ≤ p ≤ j}。 
现在你需要知道你怎么选取需要融合的宝石,才能使生成的宝石能量密度最大。

输入

第一行,一个整数 n,表示宝石个数。 
第二行, n个整数,分别表示a1至an,表示每颗宝石的能量密度,保证对于i ≠ j有 ai ≠ aj。

输出

输出一行一个整数,表示最大能生成的宝石能量密度。

样例输入

5
9 2 1 4 7

样例输出

14


题解

可持久化Trie树+STL-set

如果已经知道另外一个数可以出现的区间,那么很容易使用可持久化Trie树求出这个数与它的最大异或值。

所以我们只需要处理出每个数可能是哪些区间的次大值即可。

考虑将所有数从大到小排序,一个一个扔进set中。那么这里面所有的数都比当前的数大,在其中确定范围即可。

很容易想出某个数成为次小值的区间最大范围:最左端为 (前驱的前驱,后继) ,最右端为 (前驱,后继的后继) 。(这里都是开区间)

那么它们的并集就是 (前驱的前驱,后继的后继) ,即其中的所有数都可能出现在以当前数为次大值的区间中。

这样确定了区间以后,剩下的事情就交给可持久化Trie树就好了。按位从大到小无脑贪心即可。

需要注意一下set的边界问题,建议把0和n+1加入到set中防止越界,并减少判断的代码量。

#include <cstdio>
#include <algorithm>
#include <set>
#define N 100010
using namespace std;
struct data
{
int v , id;
}a[N];
set<int> s;
set<int>::iterator it;
int c[N * 30][2] , si[N * 30] , tot , root[N];
bool cmp(data a , data b)
{
return a.v > b.v;
}
int insert(int x , int v)
{
int tmp , y , i;
bool t;
tmp = y = ++tot;
for(i = 1 << 30 ; i ; i >>= 1)
t = v & i , c[y][t ^ 1] = c[x][t ^ 1] , x = c[x][t] , c[y][t] = ++tot , y = c[y][t] , si[y] = si[x] + 1;
return tmp;
}
int query(int x , int y , int v)
{
int ret = 0 , i;
bool t;
for(i = 1 << 30 ; i ; i >>= 1)
{
t = v & i;
if(si[c[y][t ^ 1]] - si[c[x][t ^ 1]]) ret |= i , x = c[x][t ^ 1] , y = c[y][t ^ 1];
else x = c[x][t] , y = c[y][t];
}
return ret;
}
int main()
{
int n , i , ans = 0 , l , r;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i].v) , a[i].id = i , root[i] = insert(root[i - 1] , a[i].v);
sort(a + 1 , a + n + 1 , cmp) , s.insert(0) , s.insert(n + 1);
for(i = 1 ; i <= n ; i ++ )
{
it = s.upper_bound(a[i].id) , it ++ ;
if(it == s.end()) r = n;
else r = *it - 1;
it -- , it -- ;
if(it == s.begin()) l = 1;
else l = *(--it) + 1;
s.insert(a[i].id);
if(i != 1) ans = max(ans , query(root[r] , root[l - 1] , a[i].v));
}
printf("%d\n" , ans);
return 0;
}

【bzoj3166】[Heoi2013]Alo 可持久化Trie树+STL-set的更多相关文章

  1. [BZOJ3166][Heoi2013]Alo 可持久化Trie树

    3166: [Heoi2013]Alo Time Limit: 20 Sec Memory Limit: 256 MB DescriptionWelcome to ALO ( Arithmetic a ...

  2. 【BZOJ3166】[Heoi2013]Alo 可持久化Trie树+set

    [BZOJ3166][Heoi2013]Alo Description Welcome to ALO ( Arithmetic and Logistic Online).这是一个VR MMORPG , ...

  3. bzoj 3166 [Heoi2013]Alo 可持久化Trie

    3166: [Heoi2013]Alo Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1227  Solved: 569[Submit][Status ...

  4. BZOJ 3166 HEOI2013 ALO 可持久化trie+st表

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3166(洛谷上也有) 题意概述: 给出一个序列,对于一个区间,其权值为区间中的次大值亦或区 ...

  5. [BZOJ3261&BZOJ3166]可持久化trie树及其应用

    可持久化trie树 可持久化trie树现在想来是比较好理解的了,但却看了一个下午... 相当于对于每个状态建立一条链(或者说一棵trie),求解的时候只要让两个点按照相同的步子走然后看sum的大小关系 ...

  6. 可持久化Trie树初步

    可持久化Trie树和可持久化线段树很像,依次插入信息,通过减法来进行历史版本查询. 2015年11月27日 bzoj3261 最大异或和 我们需要计算 a[p] xor a[p+1] xor ... ...

  7. [十二省联考2019]异或粽子——可持久化trie树+堆

    题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...

  8. BZOJ4477[Jsoi2015]字符串树——可持久化trie树

    题目描述 萌萌买了一颗字符串树的种子,春天种下去以后夏天就能长出一棵很大的字符串树.字符串树很奇特,树枝上都密密麻麻写满了字符串,看上去很复杂的样子.[问题描述]字符串树本质上还是一棵树,即N个节点N ...

  9. BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】

    题目分析: 很无聊的一道题目.首先区间内单点对应异或值的询问容易想到trie树.由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问.case2维护dfs序,对d ...

随机推荐

  1. Android内核剖析(1)

    Linux的启动过程 开机上电执行bootloader,将内核的前n条指令加载到系统内存中------>系统内核的初始化----------->启动应用程序. bootloader的位置装 ...

  2. Java 集合框架_下

    Map接口 特点: [1]Map接口称为键值对集合或者映射集合,其中的元素(entry)是以键值对(key-value)的形式存在. [2]Map 容器接口中提供了增.删.改.查的方式对集合进行操作. ...

  3. MySQL——数据库和 SQL 概念&&MySQL的安装

    数据库和 SQL 概念 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它的产生距今已有六十多年.随着信息技术和市场的发展,数据库变得无处不在:它在电子商务.银行系统等众多领域都 ...

  4. js函数式编程(二)-柯里化

    这节开始讲的例子都使用简单的TS来写,尽量做到和es6差别不大,正文如下 我们在编程中必然需要用到一些变量存储数据,供今后其他地方调用.而函数式编程有一个要领就是最好不要依赖外部变量(当然允许通过参数 ...

  5. Boo who-freecodecamp算法题目

    Boo who 1.要求 检查一个值是否是基本布尔类型,并返回 true 或 false. 基本布尔类型即 true 和 false 2.思路 利用switch语句判断输入的数据是true/false ...

  6. postman测试传入json

  7. Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery)

    Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery) 体验 冒号搜索 1. 获取谷歌搜索api 谷歌搜索api教程 2. 后台调用 程序入口 main.go // ...

  8. zabbix3.2安装手册

    Alexei Vladishev创建了Zabbix项目,当前处于活跃开发状态,Zabbix SIA提供支持. Zabbix是一个企业级的.开源的.分布式的监控套件 Zabbix可以监控网络和服务的监控 ...

  9. my购物车

    sum=0 a=input("请输入“水果”或“衣服”:") if a=="手机": while True: shop = { '蓝葡萄', '水蜜桃', '草 ...

  10. COMP9021--6.13

    1. break语句和continue语句都可以在循环中使用,且常与选择结构结合使用,以达到在特定条件满足时跳出循环的作用.break语句被执行,可以使整个循环提前结束.而continue语句的作用是 ...