HDU 5536 Chip Factory (字典树——序列中查找最大异或和)
来源:互联网 发布:rimworld a17 mac 编辑:程序博客网 时间:2024/05/16 14:33
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5536
题意:在一组序列中找到三个数,使两个数的和异或第三个数的值最大。
思路:我们可以知道,字典树有一个经典应用,就是在一组序列中找到一对异或和最大的两个数。只要枚举一个数,然后贪心的在字典树中找每一位不同的数字就可以了。所以我们可以建一棵字典树,先(n^2)把除了第一个数以外的两两数字的和,插入到字典树中。然后枚举每一个数字,查询异或和最大的数字。在每一个数字查询完以后,插入当前数字与其他数字相关的和,然后删除下一个数字的相关的和。不断更新答案就能求出,记得在每次样例结束以后要清书,而且用memset貌似会TLE。
但是不知道为什么,我AC的时间8s多,有时候会TLE。所以根据题目描述,100以内的时候n^3暴力一下,其余用字典树,就能过了。虽然不知道别人这么快是怎么完成的,还是提供一下我的思路。
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <iostream>#include <vector>#include <map>#include <set>#include <queue>#include <ctime>using namespace std;typedef long long ll;typedef pair<int,int> pii;#define pb push_back#define mp make_pair#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define calm (l+r)>>1const int INF=2139062143;const int maxn=1010;int n,a[maxn];struct trie{ int next[2]; int cnt;}tree[34000000];int vis;void Insert(int x){ int a[32]; for(int i=31;i>=0;i--){ a[i]=x%2; x/=2; } int rt=0; tree[rt].cnt++; for(int i=0;i<32;i++){ int t=a[i]; if(!tree[rt].next[t]){ rt=tree[rt].next[t]=++vis; } else rt=tree[rt].next[t]; tree[rt].cnt++; }}int solve(int x){ int a[32]; for(int i=31;i>=0;i--){ a[i]=x%2; x/=2; } int ans=0,rt=0; for(int i=0;i<32;i++){ int t=a[i]; if(tree[rt].next[1-t]&&tree[tree[rt].next[1-t]].cnt){ rt=tree[rt].next[1-t]; if(1-t)ans+=(1-t)*(1<<(31-i)); } else { rt=tree[rt].next[t]; if(t)ans+=t*(1<<(31-i)); } } return ans;}void Delete(int x){ int a[32]; for(int i=31;i>=0;i--){ a[i]=x%2; x/=2; } int rt=0; tree[rt].cnt--; for(int i=0;i<32;i++){ int t=a[i]; rt=tree[rt].next[t]; tree[rt].cnt--; }}void Clear(int rt){ if(tree[rt].cnt){ if(tree[rt].next[0])Clear(tree[rt].next[0]); if(tree[rt].next[1])Clear(tree[rt].next[1]); tree[rt].next[0]=tree[rt].next[1]=tree[rt].cnt=0; }}int main(){ //freopen("D://input.txt","r",stdin); int T;scanf("%d",&T); while(T--){ scanf("%d",&n); vis=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } if(n<=100){ int ans=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++)if(i!=j){ for(int k=1;k<=n;k++)if(i!=k&&j!=k){ ans=max(ans,(a[i]+a[j])^a[k]); } } } printf("%d\n",ans); continue; } for(int i=2;i<=n;i++){ for(int j=i+1;j<=n;j++){ Insert(a[i]+a[j]); } } int ans=0; for(int i=1;i<=n;i++){ ans=max(ans,solve(a[i])^a[i]); for(int j=1;j<=n;j++){ if(i!=j&&j!=i+1)Insert(a[i]+a[j]); } for(int j=1;j<=n;j++){ if(i<n&&i!=j&&i+1!=j)Delete(a[i+1]+a[j]); } } printf("%d\n",ans); Clear(0); } return 0;}
0 0
- HDU 5536 Chip Factory (字典树——序列中查找最大异或和)
- HDU 5536 Chip Factory(01字典树找最大异或值)——2015ACM/ICPC亚洲区长春站
- HDU 5536 Chip Factory——Trie + 异或运算
- hdu 5536 Chip Factory 字典树
- HDU 5536 Chip Factory 01字典树
- HDU-5536 Chip Factory(字典树)
- HDU 5536 Chip Factory (字典树)
- HDU 5536 Chip Factory(01字典树)
- hdu 5536 Chip Factory(字典树)
- HDU 5536 Chip Factory 【01字典树】
- hdu 5536 Chip Factory(字典树)
- [HDU 5536] Chip Factory (trie树+异或)
- hdu 5536 Chip Factory(水 | 字典树)
- HDU 5536 Chip Factory(字典树+经典应用)
- HDU-5536-Chip Factory【2015长春赛区】【字典树】
- HDU 5536 Chip Factory(暴力 or 01字典树)
- hdu 5536 Chip Factory(01字典树)
- HDU 5536 Chip Factory(暴力/01字典树)
- centos 7安装中文输入法
- 四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)
- Activity启动的过程
- 绝对路径和相对路径
- Createjs的控件 BitMap、MovieClip、Sprite
- HDU 5536 Chip Factory (字典树——序列中查找最大异或和)
- 大数A+B<hdoj1002>
- UIWebView和Js交互(传值)
- 分类算法之朴素贝叶斯分类(Naive Bayesian classification)
- Java中如何解决double和float精度不准的问题
- XMLBEANS的使用总结
- httpUtil
- Android Spinner 放在PopupWindow 点击报错
- 大文件上传实现