1. 程式人生 > >[HDU5536] Chip Factory

[HDU5536] Chip Factory

inf -s 新建 spa for tro pid 所有 問題

傳送門:>Here<

題意:給出一個長度為N的序列,求$Max\{ (a_i + a_j) ⊕ a_k \}$ (i,j,k均不相同) ($N \leq 1000$)

解題思路

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

  網上說得很對,凡是和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 <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#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; }

[HDU5536] Chip Factory