1. 程式人生 > >HDU 5536 字典樹

HDU 5536 字典樹

http insert span del 現場 urn include pri com

技術分享圖片

題意:就是公式。

這現場賽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 = 30
; k >=0; k--) { int c; if(x&(1<<k)) c = 1; else c = 0; if(!T[o].ch[c]) T[o].ch[c] = ++tot; o = T[o].ch[c]; T[o].size++; } } void Delete(int x) { int o = root; T[o].size--; for(int k = 30; k >=0; k--) {
int c; if(x&(1<<k)) c = 1; else c = 0; o = T[o].ch[c]; T[o].size--; } } int Query(int x) { int o = root; for(int k = 30; k >=0; k--) { int c; if(x&(1<<k)) c = 1; else c = 0; if(c==1) {
if(T[o].ch[0]&&T[T[o].ch[0]].size) o = T[o].ch[0]; else o = T[o].ch[1],x^=(1<<k); } else { if(T[o].ch[1]&&T[T[o].ch[1]].size) o = T[o].ch[1],x^=(1<<k); else o = T[o].ch[0]; } } return x; } int a[MAXN]; int main() { //freopen("in.txt","r",stdin); int T_T,n; scanf("%d",&T_T); while(T_T--) { scanf("%d",&n); int ans = 0; for(int i = 1; i <= n; i++) scanf("%d",&a[i]); for(int i = 1; i <= n; i++) Insert(a[i]); for(int i = 1; i <= n; i++) { Delete(a[i]); for(int j = i+1; j <= n; j++) { Delete(a[j]); ans = max(ans,Query(a[i]+a[j])); Insert(a[j]); } Insert(a[i]); } printf("%d\n",ans); for(int i = 1; i<=tot; i++) T[i].ch[0] = T[i].ch[1] = T[i].size = 0; tot = 1; } return 0; }

HDU 5536 字典樹