Chip Factory HDU - 5536 字典树(删除节点|增加节点)

题意:

t组样例,对于每一组样例第一行输入一个n,下面在输入n个数

你需要从这n个数里面找出来三个数(设为x,y,z),找出来(x+y)^z(同样也可以(y+z)^1)的最大值 (“^”代表异或操作,即“相同为0,不同为1”)

题解:

这一道题和Xor Sum HDU - 4825很相似

因为异或运算的特性,我们最后要求最大值,那我们就对这n个数的二进制形式建一颗字典树。然后就暴力枚举是哪两个数相加,然后在字典树中把这两个数删掉。然后在处理完的字典树中查找那个能使结果尽可能大的第三个数(至于怎么查找具体看代码)

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 using namespace std;
  7 typedef long long ll;
  8 const int maxn=2;
  9 typedef struct Trie* TrieNode;
 10 ll v[1005];
 11 struct Trie
 12 {
 13     ll val,sum;
 14     TrieNode next[2];
 15     Trie()
 16     {
 17         val=0;
 18         sum=0;
 19         memset(next,NULL,sizeof(next));
 20     }
 21 };
 22
 23 void inserts(TrieNode root,ll x,ll y)
 24 {
 25     TrieNode p = root;
 26     for(ll i=31;i>=0;--i)
 27     {
 28         ll temp=(x>>i)&1;
 29         if(p->next[temp]==NULL) p->next[temp]=new struct Trie();//printf("*%d*",temp);
 30         p->next[temp]->sum+=y;
 31         p=p->next[temp];
 32         //printf("%d ",p->sum);
 33         //p->sum+=y;
 34         //printf("%lld %lld %lld\n",i,p->sum,temp);
 35     }
 36     p->val=x;
 37 }
 38
 39 ll query(TrieNode root,ll x)
 40 {
 41     TrieNode p = root;
 42     for(ll i=31;i>=0;--i)
 43     {
 44         ll temp=((x>>i)&1)^1;
 45         if(p->next[temp]!=NULL && p->next[temp]->sum>0)
 46         {
 47             p=p->next[temp];
 48         }
 49         else
 50         {
 51             temp=(x>>i)&1;
 52             if(p->next[temp]!=NULL && p->next[temp]->sum>0)
 53                 p=p->next[temp];
 54             else //if(p->next[temp]==NULL && p->next[temp^1]==NULL)
 55             {
 56                 //printf("****");
 57                 //printf("%d\n",p->val);
 58                 return x^p->val;
 59             }
 60             //else
 61         }
 62     }
 63     return x^p->val;
 64 }
 65 void Del(TrieNode root)
 66 {
 67     for(ll i=0 ; i<2 ; ++i)
 68     {
 69         if(root->next[i])Del(root->next[i]);
 70     }
 71     delete(root);
 72 }
 73
 74 int main()
 75 {
 76     ll t,n;
 77     scanf("%lld",&t);
 78     while(t--)
 79     {
 80         TrieNode root = new struct Trie();
 81         scanf("%lld",&n);
 82         for(ll i=1;i<=n;++i)
 83         {
 84             scanf("%lld",&v[i]);
 85             inserts(root,v[i],1);
 86         }
 87         ll ans=0;
 88         for(ll i=1;i<=n;++i)
 89         {
 90             inserts(root,v[i],-1);
 91             for(ll j=i+1;j<=n;++j)
 92             {
 93                 inserts(root,v[j],-1);
 94                 ans=max(ans,query(root,v[i]+v[j]));
 95                 inserts(root,v[j],1);
 96             }
 97             inserts(root,v[i],1);
 98         }
 99         printf("%lld\n",ans);
100         Del(root);
101     }
102     return 0;
103 }

原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/12001393.html

时间: 2024-12-25 23:40:38

Chip Factory HDU - 5536 字典树(删除节点|增加节点)的相关文章

hdu5536 Chip Factory xor,字典树

hdu5536 Chip Factory   xor,字典树 Chip Factory Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 280    Accepted Submission(s): 158 Problem Description John is a manager of a CPU chip factory, the

ACM学习历程—HDU 5536 Chip Factory(xor &amp;&amp; 字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题目大意是给了一个序列,求(si+sj)^sk的最大值. 首先n有1000,暴力理论上是不行的. 此外题目中说大数据只有10组,小数据最多n只有100.(那么c*n^2的复杂度应该差不多) 于是可以考虑枚举i和j,然后匹配k. 于是可以先把所有s[k]全部存进一个字典树, 然后枚举s[i]和s[j],由于i.j.k互不相等,于是先从字典树里面删掉s[i]和s[j],然后对s[i]+s[j]这个

HDU 5536 字典树

题意:就是公式. 这现场赛O(n^3)能过,觉得太没天理了. 做法:字典树,枚举两个数,然后在字典树上贪心的跑. #include <bits/stdc++.h> using namespace std; const int MAXN = 100010; struct Trie { int ch[2],size; }T[MAXN]; int root = 1,tot = 1; void Insert(int x) { int o = root; T[o].size++; for(int k =

Trie 字典树 删除操作

字典树的删除操作: 1 没找到直接返回 2 找到叶子节点的时候,叶子节点的count标志清零,代表不是叶子节点了 3 如果当前节点没有其他孩子节点的时候,可以删除这个节点 判断是否需是叶子节点,就检查叶子节点的count标志就可以了. 判断是否有其他孩子节点就需要循环26个节点了,如果都为空,那么就没有其他孩子节点了. #include <stdio.h> #include <stdlib.h> #include <iostream> #include <vect

HDU 1800 字典树

Flying to the Mars Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10065    Accepted Submission(s): 3270 Problem Description In the year 8888, the Earth is ruled by the PPF Empire . As the popul

hdu 1075 字典树

// hdu 1075 字典树 // // 题目大意: // // 给你一个字典,即有两个字符串,一个是英文,一个是火星文,然后 // 输入一段火星文,要你翻译成英文. // // 解题思路: // // 字典树,查字典嘛,有就输出查到的,没有原样输出.将火星文插入到 // 字典树中,然后在字典输中查找.找到了,输出对应的英文,否则,原样输 // 出. // // 感悟: // // 题目确实很简单,但是,没告诉数据范围啊,导致我一直RE,原来单词 // 可能对应很长的英文啊,找人家ac的开数组

HDU 1251 字典树入门

统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submission(s): 17177    Accepted Submission(s): 7410 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前

HDU 5687 字典树插入查找删除

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5687 2016百度之星资格赛C题,直接套用字典树,顺便巩固了一下自己对字典树的理解 1 #include<stdio.h> 2 #include<string.h> 3 struct node{ 4 int next[27]; 5 int cnt; 6 void init(){ 7 cnt = 0;//计数 8 memset(next,-1,sizeof(next)); 9 } 10 };

HDU 5687 字典树入门

Problem C Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1423    Accepted Submission(s): 426 Problem Description 度熊手上有一本神奇的字典,你可以在它里面做如下三个操作: 1.insert : 往神奇字典中插入一个单词 2.delete: 在神奇字典中删除所有前缀等于给