bzoj3166 ALO 可持久化01Trie

連接:http://www.lydsy.com/JudgeOnline/problem.php?id=3166php

題意:給出一個序列,找出一個區間使得這個區間內次大值與這個區間內任意一個數的異或和最大值最大。node

首先咱們看這個次大值……可能想不出來?想不出來大概是正常的……可是若是咱們換一個角度從新放回序列中去研究,就會發現,一個數可以作出貢獻的區間就是$(前驅的前驅,後繼的後繼)$。落實到代碼上,最簡單的方法就是按數值大小排序,而後從大到小插入$set$,暴力找就好了,比某主席樹快了一個$log$c++

那麼問題就變成了在這個區間以內找到一個數使得異或值最大。這個就交給可持久化$01Trie$去解決好了然而我不會仍是現學的ide

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=50005,inf=(int)2e9;
 4 set<int>S;
 5 int ans,bin[35],n;
 6 struct ques
 7 {
 8     int val,pos;
 9     inline bool operator <(const ques &b)const
10     {
11         return val>b.val;
12     }
13 }Q[maxn];
14 struct node
15 {
16     node *ch[2];int sum;
17     node(){}
18     node(int x){sum=x;ch[0]=ch[1]=0x0;}
19 }mempool[maxn*50];int num;
20 node* root[maxn];
21 node* Newnode(int val)
22 {
23     mempool[++num]=node(val);return mempool+num;
24 }
25 void Insert(node* &now,node *las,int val,int deep)
26 {
27     now=Newnode(las->sum+1);
28     if(!(~deep))return;
29     int t=(val>>deep)&1;Insert(now->ch[t],las->ch[t],val,deep-1);now->ch[t^1]=las->ch[t^1];
30 }
31 int Query(node* L,node* R,int val,int deep)
32 {
33     if(!(~deep))return 0;
34     int t=(val>>deep)&1;
35     if(R->ch[t^1]->sum!=L->ch[t^1]->sum)
36         return bin[deep]|Query(L->ch[t^1],R->ch[t^1],val,deep-1);
37     else return Query(L->ch[t],R->ch[t],val,deep-1);
38 }
39 int haha()
40 {
41     bin[0]=1;
42     for(int i=1;i<=30;i++)bin[i]=bin[i-1]<<1;
43     scanf("%d",&n);
44     for(int i=1;i<=n;i++)scanf("%d",&Q[i].val),Q[i].pos=i;
45     root[0]=mempool;root[0]->ch[0]=root[0]->ch[1]=mempool;root[0]->sum=0;
46     for(int i=1;i<=n;i++)Insert(root[i],root[i-1],Q[i].val,31);
47     sort(Q+1,Q+n+1);
48     S.insert(-1),S.insert(inf),S.insert(-2),S.insert(inf+1),S.insert(Q[1].pos);
49     for(int i=2;i<=n;i++)
50     {
51         int l=Q[i].pos,r=Q[i].pos,x=Q[i].pos;
52         set<int>::iterator it=S.lower_bound(x),it2=it;
53         it++;r=(*it)-1;it2--;it2--;l=(*it2)+1;
54         l=max(1,l);r=min(n,r);
55         // cout<<l-1<<" "<<r<<" "<<x<<endl;
56         if(l!=r)ans=max(ans,Query(root[l-1],root[r],Q[i].val,31));
57         S.insert(Q[i].pos);
58     }
59     printf("%d\n",ans);
60 }
61 int sb=haha();
62 int main(){;}
bzoj3166
相關文章
相關標籤/搜索