处理出每个数最靠近它的左右两个比它大的数。

然后可持久化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的更多相关文章

  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: 923  Solved: 437[Submit][Status] ...

  3. Bzoj 3166 [Heoi2013] Alo 题解

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

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

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

  5. 【BZOJ 3166】【HEOI 2013】Alo

    http://www.lydsy.com/JudgeOnline/problem.php?id=3166 这道题难点在于求能对一个次大值有贡献的区间. 设这个次大值为\(a_i\),\(a_i\)左边 ...

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

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

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

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

  8. bzoj 3166 可持久化Tire

    每一个数能做出的贡献就是其两端第二个比他大的中间的数和他的异或值 按权值大小排序,按照位置扔进set,set内的元素都是比他大的,也是全的 然后Tire上跑就行了.. #include<cstd ...

  9. BZOJ - 3166 可持久化Trie 维护次大区间

    题意:给出\(a[1...n]\),找出一个连续区间\(a[l...r],r>l\),令该区间的次大值为\(a_k\),使得\(a_k⊕a_i,l≤i≤r\)最大,输出全局最优解 (这题意有点别 ...

随机推荐

  1. c++ std::string 用法

    std::string用法总结 在平常工作中经常用到了string类,本人记忆了不好用到了的时候经常要去查询.在网上摘抄一下总结一下,为以后的查询方便: string类的构造函数: string(co ...

  2. VIM配置(转载)

    注: 转载于http://www.cnblogs.com/ma6174/ 花了很长时间整理的,感觉用起来很方便,共享一下. 我的vim配置主要有以下优点: 1.按F5可以直接编译并执行C.C++.ja ...

  3. memmove和memcpy 以及strcmp strcpy几个库函数的实现

    memmove和memcpy 1.memmove 函数原型:void *memmove(void *dest, const void *source, size_t count) 返回值说明:返回指向 ...

  4. 有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面m个数。

    #include<stdio.h> #include<stdlib.h> int main() { setvbuf(stdout,NULL,_IONBF,); //使用Ecli ...

  5. ZOJ1232 Adventure of Super Mario spfa上的dp

    很早之前听说有一种dp是在图上的dp,然后是在跑SPFA的时候进行dp,所以特地找了一题关于在SPFA的时候dp的. 题意:1~a是村庄 a+1~a+b是城堡,存在m条无向边.求由a+b->1的 ...

  6. happens-before通俗理解

    原文地址:http://ifeve.com/easy-happens-before/ 学习Java并发,到后面总会接触到happens-before偏序关系.初接触玩意儿简直就是不知所云,下面是经过一 ...

  7. 恢复被win7覆盖的Ubuntu Grub

    情景:本本装有Ubuntu 12.04 + Win7 32.重装Win7 64后,Ubuntu启动菜单被覆盖. 恢复的方法有多种,思路都一样.第一步,进入Linux环境:第二步.修改Grub使其重新覆 ...

  8. Project Euler 77:Prime summations

    原题: Prime summations It is possible to write ten as the sum of primes in exactly five different ways ...

  9. Minimum_Window_Substring两种方法求解

    题目描述: Given a string S and a string T, find the minimum window in S which will contain all the chara ...

  10. Oracle配置详解

    [Oracle连接字符串][Oracle Net Manager 服务命名配置][PL/SQL 登陆数据库] 连接数据库的几个重要参数: 1. 登陆用户名:user: 2. 登录密码:password ...