Codechef REBXOR
Input
输入数据的第一行包含一个整数N,表示数组中的元素个数。
第二行包含N个整数A1,A2,…,AN。
Output
输出一行包含给定表达式可能的最大值。
Sample Input
5
1 2 3 1 2
Sample Output
6
Hint
满足条件的(l1,r1,l2,r2)有:(1,2,3,3),(1,2,4,5),(3,3,4,5)。
对于100%的数据,2 ≤ N ≤ 4*105,0 ≤ Ai ≤ 109。
分析:
刚开始的时候又没看到两个区间不能相交,又白写了
基本思路:
求出前缀异或和和后缀异或和,弄出前缀max和后缀max,遍历求最大值
(代码里面有一些小优化)
ps:
这题祭出了祖传的部分初始化(以前是:能用memset为什么不用?)
比用memset快了1700+ms,贼猛
code:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65#include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> #define ll long long using namespace std; const int maxm=4e+5; int a[maxm*32][2],cnt; int val[maxm*32];// void init(){ cnt=1; a[0][1]=a[0][0]=0;//部分初始化 } void insertt(int x){ int node=0; for(int i=31;i>=0;i--){ int v=(x>>i&1); if(!a[node][v]){ a[cnt][0]=a[cnt][1]=0;//部分初始化 a[node][v]=cnt++; } node=a[node][v]; } val[node]=x; } int ffind(int x){ int node=0; for(int i=31;i>=0;i--){ int v=(x>>i&1); if(a[node][v^1]){ node=a[node][v^1]; }else{ node=a[node][v]; } } return x^val[node]; } int b[maxm]; int pre[maxm],suf[maxm]; signed main(){ init(); int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&b[i]); pre[i]=pre[i-1]^b[i];//前缀异或和 } for(int i=n;i>=1;i--){ suf[i]=suf[i+1]^b[i];//后缀异或和 } for(int i=1;i<=n;i++){//pre数组直接作为存前缀max的数组了,废物利用 insertt(pre[i]); pre[i]=max(pre[i-1],ffind(pre[i]));//前缀max } int ans=0; init(); for(int i=1;i<=n;i++){//遍历的时候直接更新答案 insertt(suf[i]); ans=max(ans,pre[i-1]+ffind(suf[i]));// } printf("%dn",ans); return 0; }
最后
以上就是大方铅笔最近收集整理的关于bzoj4260 Codechef REBXOR (异或前缀和 +trie)的全部内容,更多相关bzoj4260内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复