1. 程式人生 > >[01字典樹]求序列完美度(求區間最大異或值)

[01字典樹]求序列完美度(求區間最大異或值)

函數表 字典 style targe efi cnblogs main code blank

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 }

[01字典樹]求序列完美度(求區間最大異或值)