• bzoj 3166 [Heoi2013]Alo 可持久化Trie


    3166: [Heoi2013]Alo

    Time Limit: 20 Sec  Memory Limit: 256 MB
    Submit: 1227  Solved: 569
    [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

    加强型数据By Hta

    题解:这里看到了xor那么就要去想按位,因为xor与各个位之间是没有关联的。

    就是每个宝石,可以操作的区间是知道的,除非它就是最大,否则找到左,右比它大的,然后

    比如l和r,在l-r的可持久化字典树中去找即可。

    好像有点麻烦,找区间的时候,是需要从大到小加入值,这样的话是可以找的。

     1 #pragma GCC optimize(2)
     2 #pragma G++ optimize(2)
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<cstdio>
     7 #include<cstring>
     8 #include<set>
     9 #include<cstdlib>
    10 
    11 #define guide set<int>::iterator
    12 #define N 50007
    13 #define inf 1000000007
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    19     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 
    23 int n;
    24 int bin[37];
    25 int ans,rt[N];
    26 struct Node
    27 {
    28     int val,pos;
    29 }a[N];
    30 set<int>q;
    31 
    32 
    33 struct trie
    34 {
    35     int cnt;
    36     int ch[37*N][2],sum[37*N];
    37     trie(){cnt=0;}
    38     int insert(int x,int val)
    39     {
    40         int root,y;root=y=++cnt;
    41         for (int i=30;i>=0;i--)
    42         {
    43             int t=val&bin[i];t>>=i;
    44             ch[y][0]=ch[x][0],ch[y][1]=ch[x][1];
    45             x=ch[x][t],y=ch[y][t]=++cnt;
    46             sum[y]=sum[x]+1;
    47         }
    48         return root;
    49     }
    50     int query(int val,int yl,int xz)
    51     {
    52         int res=0;
    53         for (int i=30;i>=0;i--)
    54         {
    55             int t=val&bin[i];t>>=i;
    56             if(sum[ch[xz][t^1]]-sum[ch[yl][t^1]])res+=bin[i],xz=ch[xz][t^1],yl=ch[yl][t^1];
    57             else xz=ch[xz][t],yl=ch[yl][t];
    58         }
    59         return res;
    60     }
    61 }trie;
    62 bool operator<(Node x,Node y){return x.val>y.val;}
    63 int main()
    64 {
    65     bin[0]=1;for(int i=1;i<=30;i++)bin[i]=bin[i-1]<<1;
    66     n=read();
    67     for (int i=1;i<=n;i++)
    68         a[i].val=read(),a[i].pos=i;
    69     for (int i=1;i<=n;i++)
    70         rt[i]=trie.insert(rt[i-1],a[i].val);
    71     q.insert(-1),q.insert(inf),q.insert(-2),q.insert(inf+1);//因为是次小
    72     sort(a+1,a+n+1),q.insert(a[1].pos);
    73     for (int i=2;i<=n;i++)
    74     {
    75         int l=a[i].pos,r=a[i].pos,x=a[i].pos;
    76         guide p,t;
    77         p=t=q.upper_bound(x);
    78         r=*t;t++;r=*t-1;
    79         l=*--p;p--;l=*p+1;
    80         l=max(1,l),r=min(n,r);
    81         if(l!=r)ans=max(ans,trie.query(a[i].val,rt[l-1],rt[r]));
    82         q.insert(x);
    83     }
    84     printf("%d",ans);
    85 }
  • 相关阅读:
    JS_ ','逗号
    JS_prettyBanner[说给自己听]
    JS_关键字详细
    CSS_圣杯
    JS_ifream通信
    [转]<!DOCTYPE html>
    JS_ImageLazylode[说给自己听]
    CSS_负边距
    JS_waterfall[说给自己听]
    JS_call,apply
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8486854.html
Copyright © 2020-2023  润新知