BZOJ 3166 Alo
处理出每个数最靠近它的左右两个比它大的数。
然后可持久化trie。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 200050
#define inf 1000000007
using namespace std;
struct num
{
int val,id;
}p[maxn];
int n,a[maxn];
int seg_ls[maxn<<],seg_rs[maxn<<],val1[maxn<<],val2[maxn<<],seg_root,seg_tot=,l1[maxn],l2[maxn],r1[maxn],r2[maxn];
int tree[maxn*][],sum[maxn*],root[maxn],bitt[],ans=,tot=;
bool cmp(num x,num y)
{
return x.val>y.val;
}
void get_table()
{
bitt[]=;
for (int i=;i<=;i++)
bitt[i]=bitt[i-]*;
}
void build_seg(int &now,int left,int right)
{
now=++seg_tot;val1[now]=;val2[now]=inf;
if (left==right) return;
int mid=(left+right)>>;
build_seg(seg_ls[now],left,mid);
build_seg(seg_rs[now],mid+,right);
}
int ask_seg(int now,int left,int right,int pos,int type)
{
if (left==right)
{
if (type==) return val1[now];
else return val2[now];
}
int mid=(left+right)>>;
if (type==)
{
if (pos<=mid) return max(val1[now],ask_seg(seg_ls[now],left,mid,pos,type));
else return max(val1[now],ask_seg(seg_rs[now],mid+,right,pos,type));
}
else
{
if (pos<=mid) return min(val2[now],ask_seg(seg_ls[now],left,mid,pos,type));
else return min(val2[now],ask_seg(seg_rs[now],mid+,right,pos,type));
}
}
void modify_seg(int now,int left,int right,int l,int r,int x,int type)
{
if ((left==l) && (right==r))
{
if (type==) val1[now]=max(val1[now],x);
else val2[now]=min(val2[now],x);
return;
}
int mid=(left+right)>>;
if (r<=mid) modify_seg(seg_ls[now],left,mid,l,r,x,type);
else if (l>=mid+) modify_seg(seg_rs[now],mid+,right,l,r,x,type);
else
{
modify_seg(seg_ls[now],left,mid,l,mid,x,type);
modify_seg(seg_rs[now],mid+,right,mid+,r,x,type);
}
}
void work(int x)
{
l1[p[x].id]=ask_seg(seg_root,,n,p[x].id,);
if (l1[p[x].id]==) l2[p[x].id]=;
else
{
if (l1[p[x].id]==) l2[p[x].id]=;
else l2[p[x].id]=ask_seg(seg_root,,n,l1[p[x].id]-,);
}
r1[p[x].id]=ask_seg(seg_root,,n,p[x].id,);
if (r1[p[x].id]==inf) {r1[p[x].id]=n+;r2[p[x].id]=n+;}
else
{
if (r1[p[x].id]==n) r2[p[x].id]=n+;
else r2[p[x].id]=ask_seg(seg_root,,n,r1[p[x].id]+,);
if (r2[p[x].id]==inf) r2[p[x].id]=n+;
}
modify_seg(seg_root,,n,p[x].id,n,p[x].id,);
modify_seg(seg_root,,n,,p[x].id,p[x].id,);
}
void insert(int b,int last,int &now,int x)
{
now=++tot;
tree[now][]=tree[last][];tree[now][]=tree[last][];
sum[now]=sum[last]+;
if (b==-) return;
int tmp=x&bitt[b];tmp>>=b;
insert(b-,tree[last][tmp],tree[now][tmp],x);
}
int ask(int b,int last,int now,int x)
{
if (b==-) return ;
int tmp=x&bitt[b];tmp>>=b;
int r=sum[tree[now][tmp^]]-sum[tree[last][tmp^]];
if (r>) return ask(b-,tree[last][tmp^],tree[now][tmp^],x)+bitt[b];
else return ask(b-,tree[last][tmp],tree[now][tmp],x);
}
int main()
{
get_table();
scanf("%d",&n);
for (int i=;i<=n;i++)
{
scanf("%d",&a[i]);
p[i].val=a[i];p[i].id=i;
}
sort(p+,p+n+,cmp);
build_seg(seg_root,,n);
for (int i=;i<=n;i++)
work(i);
for (int i=;i<=n;i++)
insert(,root[i-],root[i],a[i]);
for (int i=;i<=n;i++)
{
int l,r;
l=l2[i]+;r=r1[i]-;
ans=max(ans,ask(,root[l-],root[r],a[i]));
l=l1[i]+;r=r2[i]-;
ans=max(ans,ask(,root[l-],root[r],a[i]));
}
printf("%d\n",ans);
return ;
}
BZOJ 3166 Alo的更多相关文章
- bzoj 3166 [Heoi2013]Alo 可持久化Trie
3166: [Heoi2013]Alo Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1227 Solved: 569[Submit][Status ...
- BZOJ 3166: [Heoi2013]Alo
3166: [Heoi2013]Alo Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 923 Solved: 437[Submit][Status] ...
- Bzoj 3166 [Heoi2013] Alo 题解
3166: [Heoi2013]Alo Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1118 Solved: 518[Submit][Status ...
- BZOJ 3166 HEOI2013 ALO 可持久化trie+st表
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3166(洛谷上也有) 题意概述: 给出一个序列,对于一个区间,其权值为区间中的次大值亦或区 ...
- 【BZOJ 3166】【HEOI 2013】Alo
http://www.lydsy.com/JudgeOnline/problem.php?id=3166 这道题难点在于求能对一个次大值有贡献的区间. 设这个次大值为\(a_i\),\(a_i\)左边 ...
- BZOJ 3166 [HEOI2013]Alo (可持久化01Trie+链表)
题目大意:给你一个长度为$n$的序列,让你找出一段子序列,求其中的 次大值 异或 序列里一个数 能得到的最大值 先对序列建出可持久化$Trie$ 按元素的值从小到大遍历,设当前元素的位置是i,找出它左 ...
- BZOJ 3166: [Heoi2013]Alo 链表+可持久化trie
链表这个东西非常好用啊 ~ code: #include <bits/stdc++.h> #define N 50010 #define inf 2000400000 #define se ...
- bzoj 3166 可持久化Tire
每一个数能做出的贡献就是其两端第二个比他大的中间的数和他的异或值 按权值大小排序,按照位置扔进set,set内的元素都是比他大的,也是全的 然后Tire上跑就行了.. #include<cstd ...
- BZOJ - 3166 可持久化Trie 维护次大区间
题意:给出\(a[1...n]\),找出一个连续区间\(a[l...r],r>l\),令该区间的次大值为\(a_k\),使得\(a_k⊕a_i,l≤i≤r\)最大,输出全局最优解 (这题意有点别 ...
随机推荐
- stdint.h 文件 int8_t uint8_t int16_t uint16_t
http://blog.chinaunix.net/uid-26588712-id-3068151.html c++ 数据类型 按照posix标准,一般整型对应的*_t类型为:1字节 uint ...
- find查找指定类型文件并删除
问题描述: 查找当前目录下指定类型的文件 问题解决: (1)find命令 ...
- Ubuntu12.04 + 虚拟机VMware 9 + Secure CRT + EditPlus 本地C++开发环境搭建
1.1 软件准备 虚拟机VMware 9 Ubuntu 12.04 Secure CRT EditPlus 1.2 安装VMware 9与Ubuntu 12.04 这两个软件安装,按部就班,这里就 ...
- POJ 3258
River Hopscotch Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5961 Accepted: 2579 D ...
- 让IE系列浏览器支持HTML5(share)
引用Google的html5.js文件 <!--[if IE]> <script src=”http://html5shiv.googlecode.com/svn/trunk/htm ...
- 如何防止通过IP地址访问Tomcat管理页面
方法:建议修改webapps下面的原始文件夹的名称,比如加一个后缀: 当需要用管理页面的时候,可以将含有manager的文件夹的后缀去掉即可 manager和host-manager共2个文件夹
- ****Git 常用命令和使用思维导图
Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势. 本来想着只把最有用.最常用的 Git 命令记下来,但是总觉得这个也挺有用.那个也用 ...
- eclipse 或MyEclipse将工程进行移动的时候会对@Override报错的处理方法
有时候导入javaSE,javaEE,android 工程的时候,明明是刚刚用过的没有问题的工程,但重新导入的时候就报错. 提示The method ... must override a sperc ...
- lintcode :Invert Binary Tree 翻转二叉树
题目: 翻转二叉树 翻转一棵二叉树 样例 1 1 / \ / \ 2 3 => 3 2 / \ 4 4 挑战 递归固然可行,能否写个非递归的? 解题: 递归比较简单,非递归待补充 Java程序: ...
- Ping 命令
Ping”命令是我们在判断网络故障常用的命令 它是用来检查网络是否通畅或者网络连接速度的命令. 它所利用的原理是这样的:网络上的机器都有唯一确定的IP地址,我们给目标IP地址发送一个数据包, 对方就要 ...