HDU - 5536 Chip Factory

思路

字典树异或,题意是n个数选出3个使得(si+sj)^sk的值最大,我们对每个数构造01字典树,然后暴力枚举si,sj求和后直接在字典树上贪心。注意要在字典树上删除si和sj避免计算自己(可以使用lazy策略)。时间复杂度O(30*n^2)

代码

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
#include <bits/stdc++.h>
#define ll long long
#define INF 0x7fffffff
#define lson(x) (x<<1)
#define rson(x) ((x<<1)|1)
#define ms(a,val) memset((a),(val),(sizeof(a)))

using namespace std;

struct Trie{
int p,nexts[100010][2],val[100010];
void init(){for(int i=0;i<100010;i++)nexts[i][0]=nexts[i][1]=-1,val[i]=0;p=0;}
int newnode(){return ++p;}
void change(int x,int ch){
int now=0;
for(int pos=30;pos>=0;pos--){
int id=(x&(1<<pos))?1:0;
if(nexts[now][id]==-1)nexts[now][id]=newnode();
now=nexts[now][id];
val[now]+=ch;
}
}
int unite(int x){
int now=0,ans=0;
for(int pos=30;pos>=0;pos--){
int id=(x&(1<<pos))?1:0;
if(nexts[now][0]==-1||val[nexts[now][0]]==0)ans|=((id^1)<<pos),now=nexts[now][1];
else if(nexts[now][1]==-1||val[nexts[now][1]]==0)ans|=((id^0)<<pos),now=nexts[now][0];
else{
int ta1=ans|((id^1)<<pos),ta2=ans|((id^0)<<pos);
if(ta1>ta2)ans=ta1,now=nexts[now][1];
else ans=ta2,now=nexts[now][0];
}
}
return ans;
}
}trie;
int num[1005];
int main() {
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
trie.init();
for(int i=0;i<n;i++){
scanf("%d",&num[i]);
trie.change(num[i],1);
}
int maxs=-1;
for(int i=0;i<n-1;i++){
trie.change(num[i],-1);
for(int j=i+1;j<n;j++){
trie.change(num[j],-1);
maxs=max(maxs,trie.unite(num[i]+num[j]));
trie.change(num[j],1);
}
trie.change(num[i],1);
}
printf("%d\n",maxs);
}
return 0;
}