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

猜你喜欢

转载自www.cnblogs.com/qwerta/p/9822368.html