[01字典树]求序列完美度(求区间最大异或值)

https://nanti.jisuanke.com/t/15531

解题关键:01字典树模板,用字典树保存每个数的二进制表示,从而动态维护区间上的最大异或值,注意添加和删除都可以用于一个change函数表示。

 复杂度:$O(n\log n + {n^2}\log n)$ 

 1 #include<bits/stdc++.h>
 2 #define maxn 1005
 3 #define inf 0x3f3f3f3f
 4 using namespace std;
 5 typedef long long ll;
 6 int a[maxn];
 7 int num[32*maxn][2];
 8 int node[32*maxn][2];
 9 int val[32*maxn];
10 int sum,ans,l,r,anss,s;
11 
12 void init(){
13     sum=1;
14     ans=-inf;
15     memset(num,0,sizeof num);
16     memset(node,0,sizeof node);
17     memset(val,0,sizeof val);
18 }
19 
20 void change1(int m,int x){
21     int pos=0;
22     for(int i=30;i>=0;i--){
23         int j=x>>i&1;
24         num[pos][j]+=m;
25         if(node[pos][j]) pos=node[pos][j];
26         else{
27             memset(node[sum],0,sizeof node[sum]);
28             node[pos][j]=sum++;
29             pos=node[pos][j];
30         }
31     }
32     val[pos]=x;
33 }
34 
35 int search1(int L,int R,int x){
36     int pos=0;
37     int w=0;
38     
39     for(int i=30;i>=0;i--){
40         int j=x>>i&1;
41         if(num[pos][!j]){
42             w+=1<<i;
43             pos=node[pos][!j];
44         }
45         else    pos=node[pos][j];
46     }
47     if(w>ans) ans=w,l=L,r=R,anss=val[pos];
48 }
49 
50 int main(){
51     int t,n;
52     cin>>t;
53     while(t--){
54         init();
55         cin>>n;
56         for(int i=1;i<=n;i++) cin>>a[i],change1(1,a[i]);
57         
58         for(int i=1;i<=n;i++){
59             s=0;
60             for(int j=i;j<=n;j++){
61                 s+=a[j];
62                 change1(-1,a[j]);
63                 int w=search1(i,j,s);
64             }
65             
66             for(int j=i;j<=n;j++) change1(1,a[j]);
67         }
68         cout<<l<<" "<<r<<" "<<anss<<" "<<ans<<endl;
69     } 
70 }

 

posted @ 2017-06-03 00:17  Elpsywk  阅读(1478)  评论(0编辑  收藏  举报