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. 记录Centos7搭建ftp服务器以及遇到的各种坑

    前言 今天被经理要求搭建ftp服务器,然后就去网上搜索了一下教程.搭建成功后(遇到的坑不少)特此记录一下.因为是为了记录一下整个操作流程以防以后使用所以比较啰嗦. 目录 1.安装vsftpd 2.创建 ...

  2. 统计学习方法c++实现之八 EM算法与高斯混合模型

    EM算法与高斯混合模型 前言 EM算法是一种用于含有隐变量的概率模型参数的极大似然估计的迭代算法.如果给定的概率模型的变量都是可观测变量,那么给定观测数据后,就可以根据极大似然估计来求出模型的参数,比 ...

  3. vim 多个文件切换 :b 命令

    MiniBufExplorer插件的使用 博客分类: vim vimMiniBufExplorer 快速浏览和操作Buffer -- 插件: MiniBufExplorer 下载地址 [http:// ...

  4. 互评beta版本 - 探路者【贪吃蛇】

    基于NABCD评论,及改进建议 1)N(Need 需求) 开发本软件一方面是为了让80,90后用户重温童年的美好记忆,另一方面也是为了增加对英语学习兴趣较弱.意志力薄弱的中小学生学习英语的兴趣和动力, ...

  5. Notes of Daily Scrum Meeting(11.15)

    Notes of Daily Scrum Meeting(11.15) 今天周六我们的主要工作是把这周落下的一些工作补回来,这是写程序的最后阶段,准备进入测试阶段了,所以之前的工作 要补齐,今天大家的 ...

  6. MathExam小学一二年级计算题生成器V1.0

    MathExam小学一二年级计算题生成器v1.0 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning ...

  7. web03-OutputInfo

    电影网站:www.aikan66.com 项目网站:www.aikan66.com 游戏网站:www.aikan66.com 图片网站:www.aikan66.com 书籍网站:www.aikan66 ...

  8. 第二阶段Sprint冲刺会议4

    进展:主要实现调取手机摄像头录制,能够实现“开始”及“暂停”功能.

  9. FileInputStream 读取文件数据的输入字节流

    package com.inputstream; /* File类: 用于描述一个文件或者文件夹的. 通过File对象我们可以读取文件或者文件夹的属性数据,如果我们需要读取文件的内容数据,那么我们需要 ...

  10. web窗体之四则运算

    1,计算方法: namespace ASP.NET { public class JiSuan { public int S; public int Result { get { return S; ...