博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[HDU5536] Chip Factory
阅读量:5293 次
发布时间:2019-06-14

本文共 2538 字,大约阅读时间需要 8 分钟。

传送门:><

题意:给出一个长度为N的序列,求$Max\{ (a_i + a_j) ⊕ a_k \}$ (i,j,k均不相同)  ($N \leq 1000$)

解题思路

  既然$O(n^3)$不行,就考虑$O(n^2 \ log \ n)$的做法。

  网上说得很对,凡是和xor有关的80%都是Trie……

  将所有数的二进制建立Trie树,枚举$i,j$——此时在trie树中删去$a_i, a_j$,然后用上一篇文章的方法求得最大的异或。

  那么这道题的关键问题就在于如何删去$a_i, a_j$?每次重新建树显然又$O(n^3)$了(还不止)。

  考虑维护一个cnt数组,代表每个节点出现的次数。每一次删去的时候就像插入一样走一遍把对应节点的cnt减掉,然后在query的时候判定只能访问cnt>0的。这样很方便地处理好了问题

Code

  数组要清零

/*By DennyQi*/#include 
#include
#include
#include
#define r read()#define Max(a,b) (((a)>(b)) ? (a) : (b))#define Min(a,b) (((a)<(b)) ? (a) : (b))using namespace std;typedef long long ll;const int MAXN = 32010;const int INF = 1061109567;inline int read(){ int x = 0; int w = 1; register int c = getchar(); while(c ^ '-' && (c < '0' || c > '9')) c = getchar(); if(c == '-') w = -1, c = getchar(); while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar(); return x * w;}int T,N;int a[1010],ch[MAXN][2],cnt[MAXN],End[MAXN],num_node;bool b[35];inline void Convert(int x){ memset(b, 0, sizeof(b)); for(int i = 33; x > 0; --i){ b[i] = x%2; x >>= 1; }}inline void Insert(int x){ Convert(x); int u=0; for(int i = 1; i <= 33; ++i){ if(!ch[u][b[i]]){ ch[u][b[i]] = ++num_node; } u = ch[u][b[i]]; ++cnt[u]; } End[u] = x;}inline void Clear(int x){ Convert(x); int u=0; for(int i = 1; i <= 33; ++i){ u = ch[u][b[i]]; --cnt[u]; }}inline void Add(int x){ Convert(x); int u=0; for(int i = 1; i <= 33; ++i){ u = ch[u][b[i]]; ++cnt[u]; }}inline int Query(int k){ Convert(k); int u = 0; for(int i = 1; i <= 33; ++i){ if(!cnt[ch[u][!b[i]]]){ u = ch[u][b[i]]; } else{ u = ch[u][!b[i]]; } } return (k^End[u]);}inline void Init(){ memset(ch,0,sizeof(ch)); memset(cnt,0,sizeof(cnt)); memset(End,0,sizeof(End)); num_node = 0;}int main(){ T=r; while(T--){ Init(); N=r; for(int i = 1; i <= N; ++i){ a[i]=r; Insert(a[i]); } int ans = -1; for(int i = 1; i < N; ++i){ for(int j = i+1; j <= N; ++j){ Clear(a[i]); Clear(a[j]); ans = Max(ans, Query(a[i]+a[j])); Add(a[i]); Add(a[j]); } } printf("%d\n", ans); } return 0;}

 

转载于:https://www.cnblogs.com/qixingzhi/p/9425459.html

你可能感兴趣的文章
[Xcode 实际操作]八、网络与多线程-(5)使用UIApplication对象发送邮件
查看>>
bzoj 1093: [ZJOI2007]最大半连通子图
查看>>
springCloud的zuul基于config和github实现热更新
查看>>
python学习笔记(pip下载安装)
查看>>
CSS
查看>>
shell 管道和tee使用时获取前面命令返回值
查看>>
[LeetCode] 55. Jump Game_ Medium tag: Dynamic Programming
查看>>
[Cypress] Stub a Post Request for Successful Form Submission with Cypress
查看>>
[TypeScript] Understanding Generics with RxJS
查看>>
一、基础篇--1.3进程和线程-基本概念
查看>>
Linux kernel ‘ioapic_read_indirect’函数拒绝服务漏洞
查看>>
WordPress GRAND FlAGallery插件“s”跨站脚本漏洞
查看>>
zoj3690 Choosing number
查看>>
阳宇宸:网站开发的常用语言
查看>>
CF 600 E 启发式合并
查看>>
保险配置
查看>>
【高并发解决方案】2、集群概述
查看>>
Mysql-SqlServer区别
查看>>
Windows Phone锁屏背景相关代码
查看>>
Linux - mkdir -p a/b/c
查看>>