[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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM