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<<2],seg_rs[maxn<<2],val1[maxn<<2],val2[maxn<<2],seg_root,seg_tot=0,l1[maxn],l2[maxn],r1[maxn],r2[maxn];
int tree[maxn*50][2],sum[maxn*50],root[maxn],bitt[35],ans=0,tot=0;
bool cmp(num x,num y)
{
    return x.val>y.val;
}
void get_table()
{
    bitt[0]=1;
    for (int i=1;i<=30;i++)
        bitt[i]=bitt[i-1]*2;
}
void build_seg(int &now,int left,int right)
{
    now=++seg_tot;val1[now]=0;val2[now]=inf;
    if (left==right) return;
    int mid=(left+right)>>1;
    build_seg(seg_ls[now],left,mid);
    build_seg(seg_rs[now],mid+1,right);
}
int ask_seg(int now,int left,int right,int pos,int type)
{
    if (left==right)
    {
        if (type==1) return val1[now];
        else return val2[now];
    }
    int mid=(left+right)>>1;
    if (type==1)
    {
        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+1,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+1,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==1) val1[now]=max(val1[now],x);
        else val2[now]=min(val2[now],x);
        return;
    }
    int mid=(left+right)>>1;
    if (r<=mid) modify_seg(seg_ls[now],left,mid,l,r,x,type);
    else if (l>=mid+1) modify_seg(seg_rs[now],mid+1,right,l,r,x,type);
    else
    {
        modify_seg(seg_ls[now],left,mid,l,mid,x,type);
        modify_seg(seg_rs[now],mid+1,right,mid+1,r,x,type);
    }
}
void work(int x)
{
    l1[p[x].id]=ask_seg(seg_root,1,n,p[x].id,1);
    if (l1[p[x].id]==0) l2[p[x].id]=0;
    else
    {
        if (l1[p[x].id]==1) l2[p[x].id]=0;
        else l2[p[x].id]=ask_seg(seg_root,1,n,l1[p[x].id]-1,1);
    }
    r1[p[x].id]=ask_seg(seg_root,1,n,p[x].id,2);
    if (r1[p[x].id]==inf) {r1[p[x].id]=n+1;r2[p[x].id]=n+1;}
    else
    {
        if (r1[p[x].id]==n) r2[p[x].id]=n+1;
        else r2[p[x].id]=ask_seg(seg_root,1,n,r1[p[x].id]+1,2);
        if (r2[p[x].id]==inf) r2[p[x].id]=n+1;
    }
    modify_seg(seg_root,1,n,p[x].id,n,p[x].id,1);
    modify_seg(seg_root,1,n,1,p[x].id,p[x].id,2);
}
void insert(int b,int last,int &now,int x)
{
    now=++tot;
    tree[now][0]=tree[last][0];tree[now][1]=tree[last][1];
    sum[now]=sum[last]+1;
    if (b==-1) return;
    int tmp=x&bitt[b];tmp>>=b;
    insert(b-1,tree[last][tmp],tree[now][tmp],x);
}
int ask(int b,int last,int now,int x)
{
    if (b==-1) return 0;
     int tmp=x&bitt[b];tmp>>=b;
    int r=sum[tree[now][tmp^1]]-sum[tree[last][tmp^1]];
    if (r>0) return ask(b-1,tree[last][tmp^1],tree[now][tmp^1],x)+bitt[b];
    else return ask(b-1,tree[last][tmp],tree[now][tmp],x);
}
int main()
{
    get_table();
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        p[i].val=a[i];p[i].id=i;
    }
    sort(p+1,p+n+1,cmp);
    build_seg(seg_root,1,n);
    for (int i=1;i<=n;i++)
        work(i);
    for (int i=1;i<=n;i++)
        insert(30,root[i-1],root[i],a[i]);
    for (int i=1;i<=n;i++)
    {
        int l,r;
        l=l2[i]+1;r=r1[i]-1;
        ans=max(ans,ask(30,root[l-1],root[r],a[i]));
        l=l1[i]+1;r=r2[i]-1;
        ans=max(ans,ask(30,root[l-1],root[r],a[i]));
    }
    printf("%d\n",ans);
    return 0;
}
时间: 2024-10-12 12:38:24

BZOJ 3166 Alo的相关文章

[BZOJ 3166]Alo 可持久化01Trie

这道题入门了 可持久化01Trie 可持久化Trie多数用来解决区间异或k值之类的操作,主要是由高位到低位按位贪心就可以了 其实和主席树是一样的,Trie本身也有前缀相减性,至于空间,动态开点就可以了. 当然我们需要记录每个节点的size 对于这道题,我们可以用线段树处理出每一个数作为次大值的区间,然后去区间的Trie里面查询异或最大值就可以了 #include<iostream> #include<cstdio> #include<cstring> #define p

BZOJ 3166: [Heoi2013]Alo

3166: [Heoi2013]Alo Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 923  Solved: 437[Submit][Status][Discuss] Description Welcome to ALO ( Arithmetic and Logistic Online).这是一个VR MMORPG ,如名字所见,到处充满了数学的谜题.现在你拥有n颗宝石,每颗宝石有一个能量密度,记为ai,这些宝石的能量密度两两不同.现在你可以选

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

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3166(洛谷上也有) 题意概述: 给出一个序列,对于一个区间,其权值为区间中的次大值亦或区间中任意一个数的结果的最大值.求区间权值的最大值. 分析: 考虑每个点作为区间次大的状态,发现对于每个点至多有两个最长区间其为次大值(为了让异或结果最大当然是区间越长越好,选择最多),用二分+静态RMQ算出这两个区间再在可持久化trie上面贪心即可. 论如何现场yy可持久化数据结构23333(基于可

BZOJ 3166 HEOI2013 Alo 可持久化Trie树

题目大意:给定一个不重复的序列a,在a中任选一个区间,求区间内的次大值与区间内的任意一个其它数的最大的异或值 首先我们枚举次大值 对于一个次大值 它可能选择的另一个数的取值范围为(l,r) 其中l为这个数左侧第二个比它大的数 r为这个数右侧第二个比它大的数 在这个区间内的Trie树中贪心寻找最大值即可 这个区间怎么求呢?我们维护一棵平衡树 将数从大到小将下标加进平衡树 每加进一个下标 比它大的数的下标都在平衡树中 求两次后继就是r 求两次前驱就是l 我偷懒写了set-- #include<set

[省选]省选知识点进度

联赛之后记录一下自己的知识点学习情况(按开始时间先后顺序) 可持久化数据结构 [BZOJ 3123]森林 树上主席树 启发式合并 LCA [BZOJ 4826]影魔 区间修改主席树 标记永久化 [BZOJ 2735]世博会 主席树 切比雪夫距离转曼哈顿距离 [BZOJ 3166]Alo 可持久化01Trie [BZOJ 3689]异或之 可持久化01Trie [BZOJ 3261]最大异或和 可持久化01Trie 树套树 [COGS 257]动态排名系统 树状数组套主席树 [BZOJ 2141]

【BZOJ】【3166】【HEOI2013】Alo

可持久化Trie+set Orz zyf…… 搞区间中次大值不好搞,那么我们就反过来,找一个数,然后看它在哪些区间里是次大值…… (然而事实上我们并不用真的把这个区间具体是什么找见,只要知道它可以跟哪一段数搞Xor就可以了! 而这个区间就是……左边第二个比他大的数的位置+1 ~ 右边第二个比它大的数的位置-1 这中间所有数都可以跟它搞Xor= =,我们总能找到一个相应的区间…… (我一开始理解成,这个区间就是我们要找的,a[i]为次大数的区间,然而这不是左边有一个比它大的,右边也有一个比它大的吗

可持久化trie 学习总结

QAQ 以前一直觉得可持久化trie很难,今天强行写了一发觉得还是蛮简单的嘛 自己的模板是自己手写的,写了几道题目并没有出过错误 THUSC的第二题的解法五貌似就是可持久化trie,时间复杂度O(60*n*logn) 不过并没有正解优,听说考场上有人写可持久化树链剖分,也是6得不行QAQ 可持久化trie就是你每次插入一个单词的时候将原来trie的代码每次向下走的时候新建节点 把当前节点信息拷贝给新建节点,通常情况下还要额外对于trie的每个节点维护子树的信息 BZOJ 3261 也算是经典题目

函数式trie思想 &amp; Bzoj 3261 &amp; 3166 题解

[原题1] 3261: 最大异或和 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 497  Solved: 215 [Submit][Status] Description 给定一个非负整数序列 {a},初始长度为 N. 有   M个操作,有以下两种操作类型: 1 .A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1. 2 .Q l r x:询问操作,你需要找到一个位置 p,满足 l<=p<=r,使得: a[p] xor a[

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max