3166: [Heoi2013]Alo

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 923  Solved: 437
[Submit][Status][Discuss]

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

Source

[Submit][Status][Discuss]

首先,应该枚举选择哪个数字作为次大值,然后需要知道其对应的可以选取哪个范围内的数字作为题目中的$ap$。

范围可以通过预处理得到,方法是先用二分得到每个数左侧第一个大于这个数的地方,然后再二分出第二个大于这个数的地方。每个数到两侧第二个大于这个数的范围就是$ap$的可选范围,不含第二个大于这个数的数字。

然后,问题转化为求一个数字在一个区间内的最大异或数字,这个问题是经典的Trie树问题,尽量“反着跑”即可。但是有区间限制,并且是n组询问,所以可以用大佬的可持久化Trie或我这种蒟蒻的莫队+Trie解决。

 #include <bits/stdc++.h>

 const int siz = ;

 int n, num[siz];

 int st_maxi[siz][];

 inline void preworkST(void)
{
for (int i = ; i <= n; ++i)
st_maxi[i][] = num[i]; for (int i = ; i < ; ++i)
for (int j = ; j <= n; ++j)
if (j + ( << i) - <= n)
st_maxi[j][i] = std::max(
st_maxi[j][i - ],
st_maxi[j + ( << (i - ))][i - ]);
} inline int stMax(int l, int r)
{
if (l > r)return -; int len = r - l + , log = ; while (len >= ( << (log + )))++log; return std::max(
st_maxi[l][log],
st_maxi[r - ( << log) + ][log]);
} int nt_pre[siz];
int nt_nxt[siz]; inline void preworkNT(void)
{
for (int i = ; i <= n; ++i)
{
int val = num[i], lt = , rt = i, mid, pos = , ans = ; while (lt <= rt)
{
mid = (lt + rt) >> ; if (stMax(mid, i) > val)
lt = mid + , pos = mid;
else
rt = mid - ;
} lt = , rt = pos - ; while (lt <= rt)
{
mid = (lt + rt) >> ; if (stMax(mid, pos - ) > val)
lt = mid + , ans = mid;
else
rt = mid - ;
} nt_pre[i] = ans;
} for (int i = ; i <= n; ++i)
{
int val = num[i], lt = i, rt = n, mid, pos = n, ans = n; while (lt <= rt)
{
mid = (lt + rt) >> ; if (stMax(i, mid) > val)
rt = mid - , pos = mid;
else
lt = mid + ;
} lt = pos + , rt = n; while (lt <= rt)
{
mid = (lt + rt) >> ; if (stMax(pos + , mid) > val)
rt = mid - , ans = mid;
else
lt = mid + ;
} nt_nxt[i] = ans;
}
} struct query {
int l, r, t, ans;
}q[siz]; int s; inline bool cmp(const query &a, const query &b)
{
if (a.l / s != b.l / s)
return a.l < b.l;
else
return a.r < b.r;
} const int tri = ; int next[tri][], sum[tri], tot = ; inline void insert(int t)
{
int p = ; for (int i = ; i >= ; --i)
{
int c = (t >> i) & ; if (!next[p][c])
next[p][c] = ++tot; p = next[p][c]; ++sum[p];
}
} inline void remove(int t)
{
int p = ; for (int i = ; i >= ; --i)
{
int c = (t >> i) & ; if (!next[p][c])
next[p][c] = ++tot; p = next[p][c]; --sum[p];
}
} inline int query(int t)
{
int ret = , p = ; for (int i = ; i >= ; --i)
{
int c = (t >> i) & ; if (sum[next[p][c^]])
p = next[p][c^], ret |= ( << i);
else if (sum[next[p][c]])
p = next[p][c];
else
return ;
} return ret;
} signed main(void)
{
scanf("%d", &n); for (int i = ; i <= n; ++i)
scanf("%d", num + i); preworkST(); preworkNT(); for (int i = ; i <= n; ++i)
{
q[i].l = nt_pre[i];
q[i].r = nt_nxt[i];
q[i].t = num[i];
q[i].ans = ;
} s = sqrt(n); std::sort(q + , q + + n, cmp); int lt = , rt = , maxi = stMax(, n); for (int i = ; i <= n; ++i)
{
while (lt < q[i].l)remove(num[lt++]);
while (lt > q[i].l)insert(num[--lt]);
while (rt > q[i].r)remove(num[rt--]);
while (rt < q[i].r)insert(num[++rt]);
if (q[i].t != maxi)q[i].ans = query(q[i].t);
} int answer = ; for (int i = ; i <= n; ++i)
answer = std::max(answer, q[i].ans); printf("%d\n", answer);
}

@Author: YouSiki

BZOJ 3166: [Heoi2013]Alo的更多相关文章

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

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

  2. Bzoj 3166 [Heoi2013] Alo 题解

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

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

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

  4. BZOJ 3166 [HEOI2013]Alo (可持久化01Trie+链表)

    题目大意:给你一个长度为$n$的序列,让你找出一段子序列,求其中的 次大值 异或 序列里一个数 能得到的最大值 先对序列建出可持久化$Trie$ 按元素的值从小到大遍历,设当前元素的位置是i,找出它左 ...

  5. BZOJ 3166: [Heoi2013]Alo 链表+可持久化trie

    链表这个东西非常好用啊 ~ code: #include <bits/stdc++.h> #define N 50010 #define inf 2000400000 #define se ...

  6. BZOJ3166: [Heoi2013]Alo

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

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

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

  8. P4098 [HEOI2013]ALO

    最近这个家伙去哪了,为啥一直不更博客了呢?原来他被老师逼迫去补了一周的文化课,以至于不会把班里的平均分拉掉太多.好了,我们来看下面这道题目: P4098 [HEOI2013]ALO 题目描述 Welc ...

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

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

随机推荐

  1. Revit开发小技巧——撤销操作

    最近开发Revit命令需要限制某些操作,思路是监控用户操作,如果达到限制条件,将操作回退.思路有两种: 1.调用WindowsAPI,发送快捷命令Ctrl+Z. 2.通过Revit底层提供DLL找到回 ...

  2. java并发之线程池的使用

    背景 当系统并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要消耗大量的系统资源. 所以需要一个办法使得线程可以 ...

  3. vue处理循环列表动态数据问题

    调用方法:Vue.set( target, key, value ) target:要更改的数据源(可以是对象或者数组) key:要更改的具体数据 value :重新赋的值 <!DOCTYPE ...

  4. JavaScript学习笔记(六)—— 异步编码

    第七章 异步编码 1  事件处理程序 处理程序:即网页加载完毕后将执行的代码,称回调函数或监听器: 包含:处理函数+window.onload=函数名; <script language=&qu ...

  5. jsp内置对象 转发与重定向的区别

    jsp 内置对象  转发与重定向的比较 重定向和转发有一个重要的不同:当使用转发时,JSP容器将使用一个内部的方法来调用目标页面,新的页面继续处理同一个请求,而浏览器将不会知道这个过程. 与之相反,重 ...

  6. day13 内置函数

    参考资料: https://www.processon.com/view/link/5b4ee15be4b0edb750de96ac 内置函数: 作⽤域相关: locals()     返回当前作用域 ...

  7. Python-opencv摄像头图像捕获

    实例一 (灰色调度) #!/usr/bin/env python # _*_ coding:utf-8 _*_ import cv2 as cv import numpy as np capture ...

  8. 【贪心算法】POJ-1328 区间问题

    一.题目 Description Assume the coasting is an infinite straight line. Land is in one side of coasting, ...

  9. week4c:个人博客作业

    6.具体程序: #include<stdio.h>#include<stdlib.h>#include<math.h>void Udecide_n();int De ...

  10. C1WPF制作OLAP Cube浏览工具

    经过前期一段时间对WPF的学习了解,相信大家对WPF有了一定的了解.今天我们一起来了解使用Component One(简称C1)的WPF控件制作CUBE浏览工具.其实这个OLAP控件官方已经有了很详细 ...