HDU 5536 01字典树

来源:互联网 发布:淘宝商家物流信息 编辑:程序博客网 时间:2024/05/22 19:58

题目链接


题意:从n个数s1,s2...sn中选出3个下标不同的数,求:max(i,j,k)((si+sj)sk)

思路:
考虑将所有数插入字典树,然后枚举i,j,从字典树中删去si,sj后拿(si+sj)去匹配最大值即可。


代码:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const int A = 1e3 + 10;int Trie[A<<5][2],val[A<<5],cnt[A<<5],a[A],tot,n;void insert(ll v,int add){    int u = 0;    for(int i=32 ;i>=0 ;i--){        int c = (v>>i)&1;        if(!Trie[u][c]){            Trie[u][c] = ++tot;            cnt[tot] = 0;val[tot] = 0;            memset(Trie[tot],0,sizeof(Trie[tot]));        }        u = Trie[u][c];        cnt[u]+=add;    }    val[u] = v;}ll query(ll v){    int u = 0;    for(int i=32 ;i>=0 ;i--){        int c = (v>>i)&1;        if(cnt[Trie[u][c^1]]>0) u = Trie[u][c^1];        else                    u = Trie[u][c];    }    return val[u];}int main(){    int T;scanf("%d",&T);    while(T--){        tot = 0;memset(Trie[0],0,sizeof(Trie[0]));        scanf("%d",&n);        for(int i=1 ;i<=n ;i++) {scanf("%d",&a[i]);insert(a[i],1);}        ll ans = 0;        for(int i=1 ;i<=n ;i++){            insert(a[i],-1);            for(int j=i+1 ;j<=n ;j++){                insert(a[j],-1);                ll now = a[i]+a[j];                ans = max(ans,1LL*now^query(now));                insert(a[j],1);            }            insert(a[i],1);        }        printf("%I64d\n",ans);    }    return 0;}