3166: [Heoi2013]Alo

Time Limit: 20 Sec Memory Limit: 256 MB

Description
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}。
现在你需要知道你怎么选取需要融合的宝石,才能使生成的宝石能量密度最大。
Input
第一行,一个整数 n,表示宝石个数。
第二行, n个整数,分别表示a1至an,表示每颗宝石的能量密度,保证对于i ≠ j有 ai ≠ aj。
Output
输出一行一个整数,表示最大能生成的宝石能量密度。
Sample Input
5
9 2 1 4 7
Sample Output
14
HINT
【样例解释】
选择区间[1,5],最大值为 7 xor 9。
对于 100%的数据有 1 ≤ n ≤ 50000, 0 ≤ ai ≤ 10^9

题解:

我们不难想到在单调队列题目中用过的一种思路:枚举每个点作为次小值,去找比他大的值,那么能满足题目要求的区间大概长这样:

上图中两端被扩起来的区间即为所求。那么现在我们的问题转化为去找每个点从左从右数第二个比他大的值的位置。

这个显然不能用单调队列搞……

由于题目保证每一个数据都不相等,所以我们考虑搞一个set,把数据按权值大小排序,然后插入元素的下标。

由于在插入某个值的时候,比他大的都已经插入了

所以这个时候查询比他大2名的和小2名的即可。

具体实现有一些边界处理的小细节,读者可以结合下面代码思考一下。代码见下:

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
const int N=;
struct Trie
{
Trie *ch[];int size;
Trie(){ch[]=ch[]=,size=;}
}*null=new Trie(),*root[N];
inline Trie* newTrie(){Trie *o=new Trie();o->ch[]=o->ch[]=null;return o;}
int cnt,stack[N],top;LL bin[];
set<int>st;
struct node{int pos,val;}a[N];
inline bool mt(const node &a,const node &b){return a.val>b.val;}
void Insert(Trie *&o,Trie *old,int val,int i)
{
if(i<)return;
int d=((val&bin[i])==bin[i]);
o->ch[d]=newTrie(),o->ch[d^]=old->ch[d^];
o->ch[d]->size=old->ch[d]->size+;
Insert(o->ch[d],old->ch[d],val,i-);
}
inline int query(int a,int b,int val)
{
int ret=;
Trie *x=root[a],*y=root[b];
for(int i=;~i;i--)
{
int d=(val&bin[i])>>i;
if(y->ch[d^]->size-x->ch[d^]->size)
ret|=bin[i],y=y->ch[d^],x=x->ch[d^];
else y=y->ch[d],x=x->ch[d];
}
return ret;
}
int main()
{
int n;scanf("%d",&n);
bin[]=;for(int i=;i<=;i++)bin[i]=bin[i-]<<;
for(int i=;i<=n;i++)root[i]=newTrie();
null->ch[]=null->ch[]=null;
for(int i=;i<=n;i++)
scanf("%d",&a[i].val),a[i].pos=i,Insert(root[i],root[i-],a[i].val,);
sort(a+,a+n+,mt);
st.insert(-);st.insert(-);st.insert(-);
st.insert(n+);st.insert(n+);st.insert(n+);
st.insert(a[].pos);
int ans=;
for(int i=;i<=n;i++)
{
set<int>::iterator a1,a2;
a2=st.lower_bound(a[i].pos);
a1=a2;a2++;a1--;a1--;
int l=*a1+,r=*a2-;
l=max(l,),r=min(n,r);
ans=max(ans,query(l-,r,a[i].val));
st.insert(a[i].pos);
}
printf("%d\n",ans);
}

[BZOJ3166][Heoi2013]Alo 可持久化Trie树的更多相关文章

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

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

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

    题目描述 Welcome to ALO ( Arithmetic and Logistic Online).这是一个VR MMORPG ,如名字所见,到处充满了数学的谜题.现在你拥有n颗宝石,每颗宝石 ...

  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. day 7 __new___

    1 __new__方法 创建对象 实质是:调用父类的__new__方法创建的对象 class Dog(object): def __init__(self): print("---init方 ...

  2. js页面动态时间展示

    效果图: 具体代码 js代码 <script type="text/javascript"> var t = null; t = setTimeout(time,100 ...

  3. 洛谷P2464 [SDOJ2008]郁闷的小J

    洛谷P2464 [SDOJ2008]郁闷的小J 题目描述 小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架.虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他 ...

  4. 阿里云Ubuntu 14.04 + Nginx + .net core + MySql

    前段时间帮朋友写了一个网站,现在做一个记录. .Net Core 安装: curl https://packages.microsoft.com/keys/microsoft.asc | gpg -- ...

  5. TensorFlow深度学习实战---图像数据处理

    图像的亮度.对比度等属性对图像的影响非常大,这些因素都会影响最后的识别结构.当然,复杂的预处理过程可能会导致训练效率的下降(利用TensorFlow中多线程处理输入数据的解决方案). 同一不同的原始数 ...

  6. 爬虫2.5-scrapy框架-下载中间件

    目录 scrapy框架-下载中间件 scrapy框架-下载中间件 middlewares.py中有两个类,一个是xxSpiderMiddleware类 一个是xxDownloaderMiddlewar ...

  7. Windows操作系统C盘占用空间过多

    Windows操作系统C盘占用空间过多 大部分的windows电脑用户在长时间使用PC时都会遇到一个问题,就是C盘占用的空间会越来越多,乃至占满整个C盘. 后来在百度了一波,发现各种方法都试过了,也不 ...

  8. 高可用Kubernetes集群-10. 部署kube-proxy

    十二.部署kube-proxy 1. 创建kube-proxy证书 1)创建kube-proxy证书签名请求 # kube-proxy提取CN作为客户端的用户名,即system:kube-proxy. ...

  9. 第五章—if语句

    5-1 条件测试 :编写一系列条件测试:将每个测试以及你对其结果的预测和实际结果都打印出来.你编写的代码应类似于下面这样: car = 'subaru' print("Is car == ' ...

  10. 20172314 蓝墨云课堂实践ASL

    由于去跳啦啦操没有上课... 介绍 折半查找,又称作二分查找.这个查找的算法的特点,就是,要求数据要是有序的. 1 ,存储结构一定是顺序存储 2 ,关键字大小必须有序排列 然后,利用这组有序的数据之间 ...