zoukankan      html  css  js  c++  java
  • BZOJ 3166 [HEOI2013]Alo (可持久化01Trie+链表)

    题目大意:给你一个长度为$n$的序列,让你找出一段子序列,求其中的 次大值 异或 序列里一个数 能得到的最大值

    先对序列建出可持久化$Trie$

    按元素的值从小到大遍历,设当前元素的位置是i,找出它左右离它最近第一个比$a_{i}$的位置$l1,r1$,再找出第二个比$a_{i}$大的位置$l2,r2$,这个可以用双向链表维护,保证$l1$和$r1$是$i$在链表里的$L_{i},R_{i}$

    那么$a_{i}$能作为次大值出现的区间为$[l2+1,r1-1]$和$[l1+1,r2-1]$

    把$a_{i}$放到可持久化$Trie$里,找出和上述区间内的数异或能得到的最大值

    然后把$a_{i}$从链表内删除,因为$a_{i}$不会作为最大值影响后面的元素

     1 #include <cmath>
     2 #include <queue>
     3 #include <vector>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <algorithm>
     7 #define N1 50100
     8 #define N2 1600000
     9 #define MM 100
    10 #define ll long long
    11 #define dd double  
    12 #define uint unsigned int
    13 #define mod 1000000007
    14 #define idx(X) (X-'a')
    15 using namespace std;
    16 
    17 int gint()
    18 {
    19     int ret=0,fh=1;char c=getchar();
    20     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
    21     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
    22     return ret*fh;
    23 }
    24 int bin[25];
    25 struct Trie{
    26 int ch[N2][2],num[N2],root[N1],tot;
    27 void init()
    28 {
    29     tot=1;int x=1;
    30     for(int i=29;i>=0;i--){
    31         ch[x][0]=++tot;
    32         x=ch[x][0];
    33         num[x]=1;
    34     }
    35 }
    36 void insert(int s,int rt1,int rt2,int w)
    37 {
    38     int x,y,p;
    39     y=root[rt1];
    40     root[rt2]=++tot,x=root[rt2];
    41     for(int i=29;i>=0;i--){
    42         p=(s&bin[i])?1:0;
    43         ch[x][p]=++tot;
    44         ch[x][p^1]=ch[y][p^1];
    45         num[ch[x][p]]=num[ch[y][p]]+w;
    46         x=ch[x][p],y=ch[y][p];
    47     }
    48 }
    49 uint query(int l,int r,uint s)
    50 {
    51     int x,y,p;uint ans=0;
    52     x=root[r],y=l<0?0:root[l];
    53     for(int i=29;i>=0;i--){
    54         p=(s&bin[i])?1:0;
    55         if(num[ch[x][p^1]]-num[ch[y][p^1]]>0){
    56             x=ch[x][p^1],y=ch[y][p^1];
    57             ans|=bin[i];
    58         }else if(num[ch[x][p]]-num[ch[y][p]]>0){
    59             x=ch[x][p],y=ch[y][p];
    60         }else break;
    61     }return ans;
    62 }
    63 }T;
    64 
    65 int n,m;
    66 uint a[N1];
    67 int L[N1],R[N1];
    68 struct node{uint w;int id;}b[N1];
    69 int cmp(node s1,node s2){return s1.w<s2.w;}
    70 
    71 int main()
    72 {
    73     //freopen("1.in","r",stdin);
    74     scanf("%d",&n);
    75     for(int i=0;i<=29;i++)
    76         bin[i]=(1<<i);
    77     T.init();
    78     for(int i=1;i<=n;i++){
    79         a[i]=gint();
    80         b[i].w=a[i],b[i].id=i;
    81         T.insert(a[i],i-1,i,1);
    82         L[i]=i-1,R[i]=i+1;
    83     }
    84     sort(b+1,b+n+1,cmp);
    85     int l1,r1,l2,r2;
    86     uint s1,s2,ans=0;
    87     for(int j=1;j<=n;j++){  
    88         int i=b[j].id;
    89         l1=L[i],r1=R[i];
    90         l2=L[l1],r2=R[r1];
    91         s1=0,s2=0;
    92         if(l1!=0) s1=T.query(l2,r1-1,a[i]);
    93         if(r1!=n+1) s2=T.query(l1,r2-1,a[i]);
    94         ans=max(ans,max(s1,s2));
    95         L[R[i]]=L[i],R[L[i]]=R[i];
    96     }
    97     printf("%u
    ",ans);
    98     return 0;
    99 }
  • 相关阅读:
    2020软件工程作业00
    2020软件工程作业03
    2020软件工程作业02
    软件工程作业01
    2020软件工程作业06
    2020软件工程作业05
    问题清单
    2020软件工程作业04
    2020软件工程作业02
    2020软件工程作业1
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10028159.html
Copyright © 2011-2022 走看看