HDU 5536 Chip Factory(字典树)

题目戳这

题意:给你n个数,从中选出三个数a,b,c,然后(a+b)^c,这个式子的值是最大的。

思路:如果来三个for循环,果断TLE,所以想到了字典树,就是先把所有的数字都插进去,在查询的时候就先把确定了的那两个数字删掉,然后在字典树中求出异或的最大值,得到结果后,再把两个数字插回去。

P.S.一开始我的数组开到了45*10^5+10,然后他给我TLE,然后当我把数组开到10^5+10的时候,A了···········,居然是数组爆我时间了,我勒个擦。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define ll long long
#define maxn 100010
#define PI acos(-1.0)    //圆周率
const ll INF = 1e18;
const int len=31;
using namespace std;
struct node
{
    int sz;
    int ch[maxn][2];
    int sum[maxn];

    void trie()
    {
        sz=1;
        memset(ch,0,sizeof(ch));
        memset(sum,0,sizeof(sum));
    }

    void add(int x)
    {
        int u=0;
        bool f;
        for(int i=len;i>=0;i--)
        {
            f=x&(1<<i);
            if(ch[u][f]==0)  ch[u][f]=sz++;
            u=ch[u][f];
            sum[u]++;
        }
    }

    void del(int x)
    {
        int u=0;
        bool f;
        for(int i=len;i>=0;i--)
        {
            f=x&(1<<i);
            u=ch[u][f];
            sum[u]--;
        }
    }

    int query(int x)
    {
        int u=0;
        bool f;
        int cnt=0;
        for(int i=len;i>=0;i--)
        {
            f=x&(1<<i);
            if(sum[ch[u][!f]])  f=!f;

            u=ch[u][f];
            cnt=cnt|(f<<i);
        }

        return cnt;
    }
}st;
int T,n;
int num[1100];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        st.trie();
        int k=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&num[i]);
            st.add(num[i]);
        }

        ll ans=0;
        ll big=0;
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                st.del(num[i]);
                st.del(num[j]);
                int nut=st.query(num[i]+num[j]);

                big=nut^(num[i]+num[j]);

                ans=ans>big?ans:big;

                st.add(num[i]);
                st.add(num[j]);
            }
        }

        printf("%d
",ans);
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/2cm-miao/p/5875155.html