[HDOJ5536] Chip Factory(字典树,异或,贪心)

题目链接:https://vjudge.net/problem/HDU-5536

题意:一个数列中寻找三个不同的数ai,aj,ak,使得(ai+aj) xor ak值最大,求这个最大的值。

预处理sum(i,j)=ai+aj,之后把ai所有的数拆成二进制丢进字典树里,枚举sum,并且在字典树里把对应的ai aj删掉后,从高到低位贪心地找与当前数字位不同的,之后把这一位异或起来。

好气啊,重现的时候写搓了,当时真的delete了节点,现在发现根本不用。每个节点统计经过当前节点的数字的个数,查询的时候遇到下一个是0那就走另一个分支就行了,而且这样删数字也极其容易。。

好水啊。。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef struct Node {
 5     Node* next[2];
 6     int sign;
 7     Node() { next[0] = next[1] = NULL; sign = 0; }
 8 }Node;
 9 
10 typedef struct Cao {
11     int i, j, sum;
12 }Cao;
13 const int maxn = 1010;
14 int n, ncnt;
15 int s[maxn];
16 int digit[55];
17 vector<Cao> sum;
18 
19 void insert(Node* rt, int val) {
20     Node* tmp = rt;
21     for(int i = 30; i >= 0; i--) {
22         int id = ((1 << i) & val) ? 1 : 0;
23         if(tmp->next[id] == NULL) tmp->next[id] = new Node();
24         tmp = tmp->next[id];
25         tmp->sign++;
26     }
27 }
28 
29 int gao(Node* rt, int val) {
30     Node* tmp = rt;
31     for(int i = 30; i >= 0; i--) {
32         int id = ((1 << i) & val) ? 1 : 0;
33         if(id == 1) {
34             if(tmp->next[0] != NULL && tmp->next[0]->sign) {
35                 tmp = tmp->next[0];
36             }
37             else {
38                 tmp = tmp->next[1];
39                 val ^= (1 << i);
40             }
41         }
42         else {
43             if(tmp->next[1] != NULL && tmp->next[1]->sign) {
44                 tmp = tmp->next[1];
45                 val ^= (1 << i);
46             }
47             else tmp = tmp->next[0];
48         }
49     }
50     return val;
51 }
52 
53 void erase(Node* rt, int val) {
54     Node* tmp = rt;
55     for(int i = 30; i >= 0; i--) {
56         int id = ((1 << i) & val) ? 1 : 0;
57         tmp = tmp->next[id];
58         tmp->sign--;
59     }
60 }
61 
62 int main() {
63     // freopen("in", "r", stdin);
64     int T;
65     scanf("%d", &T);
66     while(T--) {
67         scanf("%d", &n);
68         for(int i = 1; i <= n; i++) scanf("%d", &s[i]);
69         Node* rt = new Node(); sum.clear();
70         for(int i = 1; i <= n; i++) for(int j = i+1; j <= n; j++) sum.push_back(Cao{i,j,s[i]+s[j]});
71         for(int i = 1; i <= n; i++) insert(rt, s[i]);
72         int ret = 0;
73         for(int i = 0; i < sum.size(); i++) {
74             erase(rt, s[sum[i].i]); erase(rt, s[sum[i].j]);
75             int tmp = gao(rt, sum[i].sum);
76             if(ret < tmp) ret = tmp;
77             insert(rt, s[sum[i].i]); insert(rt, s[sum[i].j]);
78         }
79         printf("%d\n", ret);
80     }
81     return 0;
82 }

 

posted @ 2017-05-04 16:43  Kirai  阅读(196)  评论(0编辑  收藏  举报