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