zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    python 基础知识点整理 和详细应用
    DrawText的使用
    虚拟机无法联网解决方法
    Android中ExpandableListView控件基本使用
    PageRank算法
    怎样绕过工信部备案系统
    ASSERT函数
    一键安装 gitlab7 on rhel6.4 并设置邮件发送
    Android Bundle类
    ORACLE EXP命令
  • 原文地址:https://www.cnblogs.com/2cm-miao/p/5875155.html
Copyright © 2011-2022 走看看