1. 程式人生 > >*hdu 5536(字典樹的運用)

*hdu 5536(字典樹的運用)

Input The first line of input contains an integer T indicating the total number of test cases.

The first line of each test case is an integer n, indicating the number of chips produced today. The next line has n integers s1,s2,..,sn, separated with single space, indicating serial number of each chip.

1T1000
3n1000
0si109
There are at most 10 testcases with n
>100

Output For each test case, please output an integer indicating the checksum number in a line.
Sample Input 2 3 1 2 3 3 100 200 300
Sample Output 6 400 題意:求下面這個公式的最大值:
maxi,j,k(si+sj)sk

思路:如果用普通方法你要分別列舉3個數,n^3感覺會超時的。

然而完全莫有想到能用字典樹,你先把所有的數儲存下來,然後刪去要用的i和j,再在裡面找出能和a[i]+a[j]異或

出的最大值。相當於值需要列舉i和j即可。          /*好機智

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
#include <algorithm>
#include <functional>
typedef long long ll;
using namespace std;

int a[1005];

struct node
{
    int number;
    int flag;
    int next[2];
    void ini()
    {
        next[0] = next[1] = 0;
        flag = 0;
    }
} pnode[1000005];
int root = 0;
int tot;

void inser(int x)
{
    int tt = root;
    for(int i = 30; i >= 0; i --)
    {
        int t;
        if(x & (1<<i))t = 1;
        else  t = 0;
        if(!pnode[tt].next[t])
        {
            pnode[tt].next[t] = ++tot;
            pnode[tot].number = t;
        }
        tt = pnode[tt].next[t];
        pnode[tt].flag++;
    }
}

void delet(int x)
{
    int tt = root;
    for(int i = 30; i >= 0; i--)
    {
        int t;
        if(x & (1<<i))t = 1;
        else  t = 0;
        tt = pnode[tt].next[t];
        pnode[tt].flag --;
    }
}

int query(int x)
{
    int tt = root;
    for(int i = 30; i >= 0; i--)
    {
        int t;
        if(x & (1<<i)) t = 1;
        else t = 0;
        if(t == 1)
        {
            int nex = pnode[tt].next[0];
            if(pnode[nex].flag > 0 && nex) tt = pnode[tt].next[0];
            else
            {
                tt = pnode[tt].next[1];
                x ^= (1<<i);
            }
        }
        else
        {
            int nex = pnode[tt].next[1];
            if(pnode[nex].flag > 0 && nex)
            {
                tt = pnode[tt].next[1];
                x ^= (1<<i);
            }
            else tt = pnode[tt].next[0];
        }
    }
    return x;
}

int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        int ans = 0;
        scanf("%d",&n);
        tot = 0;
        for(int i = 0; i < n; i++)   scanf("%d",a+i);
        for(int i = 0; i < n; i++)   inser(a[i]);

        for(int i = 0; i < n; i++)
        {
            delet(a[i]);
            for(int j = i+1; j < n; j++)
            {
                delet(a[j]);
                ans = max(ans,query(a[i] + a[j]));
                inser(a[j]);
            }
            inser(a[i]);
        }
        for(int i = 0;i < tot;i++)
        {
            pnode[i].ini();
        }
        printf("%d\n",ans);
    }
    return 0;
}


Input The first line of input contains an integer T indicating the total number of test cases.

The first line of each test case is an integer n, indicating the number of chips produced today. The next line has n integers s1,s2,..,sn, separated with single space, indicating serial number of each chip.

1T1000
3n1000
0si109
There are at most 10 testcases with n>100
Output For each test case, please output an integer indicating the checksum number in a line.
Sample Input 2 3 1 2 3 3 100 200 300
Sample Output 6 400