zoukankan      html  css  js  c++  java
  • [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
    ", ret);
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    C
    A
    L
    G
    关于html()、val()、text()
    EL表达式
    JSON书写格式示例
    Servlet获取项目名的方法
    修改完Servlet后不用重启项目的设置方法
    浮动
  • 原文地址:https://www.cnblogs.com/kirai/p/6808001.html
Copyright © 2011-2022 走看看