1. 程式人生 > >「LOJ#10051」「一本通 2.3 例 3」Nikitosh 和異或 「LOJ#10050」「一本通 2.3 例 2」The XOR Largest Pair(Trie

「LOJ#10051」「一本通 2.3 例 3」Nikitosh 和異或 「LOJ#10050」「一本通 2.3 例 2」The XOR Largest Pair(Trie

題目描述

原題來自:CODECHEF September Challenge 2015 REBXOR

1​​r1​​<l2​​r2​​N,x⨁yx\bigoplus yx⨁y 表示 xxx 和 yyy 的按位異或。

輸入格式

輸出格式

輸出一行包含給定表示式可能的最大值。

樣例

資料範圍與提示

5​​,0Ai​​109​​。

題解

首先記錄異或字首和$s[i]=a[1]⨁a[2]a[3]...a[i]$。

設$l[i]$為以$i$結尾的區間中,異或值的最大值。

因為異或有$xx=0$的性質,所以區間$[l,r]$的異或值

$=a[l]a[l+1]...a[r]$

$=(a[1]a[2]a[3]...a[l-1])(a[1]a[2]a[3]...a[r])$

$=s[l-1]s[r]$,

所以求$l[i]$,轉化為找$j<i$,使得$s[j]s[i]$最大。

轉化為「LOJ#10050」「一本通 2.3 例 2」The XOR Largest Pair(Trie

以相似的方法可以求出$r[i]$(以$i$開頭的區間中,異或值的最大值)。

在實際操作的過程中可以$l[i]=max(l[i-1],find(x))$,這樣$ans=max(l[i]+r[i+1])$就行了。

書上的操作是直接$l[i]=find(x)$然後$ans=max(l[i]+r[i+1])$,感覺不能理解qwq

 1 編號     題目     狀態     分數     總時間     記憶體     程式碼 / 答案檔案     提交者     提交時間
 2 #237651     #10051. 「一本通 2.33」Nikitosh 和異或    Accepted     100
2765 ms 43900 KiB C++ / 1.2 K qwerta 2018-10-20 17:15:56 3 4 #include<iostream> 5 #include<cstring> 6 #include<cstdio> 7 #include<cmath> 8 using namespace std; 9 int s[400003]; 10 int l[400003]; 11 int r[400003]; 12 struct emm{ 13 int nxt[2]; 14 }a[12800003]; 15 int cnt=0; 16 int b[33]; 17 void add(int x) 18 { 19 int j=-1; 20 memset(b,0,sizeof(b)); 21 while(x) 22 { 23 b[++j]=x&1; 24 x>>=1; 25 } 26 int k=0; 27 for(int j=32;j>=0;--j) 28 { 29 if(!a[k].nxt[b[j]]) 30 a[k].nxt[b[j]]=++cnt; 31 k=a[k].nxt[b[j]]; 32 } 33 return; 34 } 35 int find(int x) 36 { 37 int now=0,k=0; 38 for(int j=32;j>=0;--j) 39 { 40 if(a[k].nxt[1-b[j]]) 41 { 42 now+=(1<<j); 43 k=a[k].nxt[1-b[j]]; 44 } 45 else k=a[k].nxt[b[j]]; 46 } 47 return now; 48 } 49 int main() 50 { 51 //freopen("a.in","r",stdin); 52 int n; 53 scanf("%d",&n); 54 for(int i=1;i<=n;++i) 55 scanf("%d",&s[i]); 56 int x=0; 57 for(int i=1;i<=n;++i) 58 { 59 x^=s[i];//這裡的x為字首和 60 add(x); 61 l[i]=max(l[i-1],find(x)); 62 } 63 //重做一次找r[i] 64 memset(a,0,cnt+1); 65 x=0,cnt=0; 66 for(int i=n;i;--i) 67 { 68 x^=s[i]; 69 add(x); 70 r[i]=max(r[i+1],find(x)); 71 } 72 int ans=0; 73 for(int i=1;i<n;++i) 74 ans=max(ans,l[i]+r[i+1]); 75 cout<<ans; 76 return 0; 77 }