• [HDU5536] Chip Factory


    传送门:>Here<

    题意:给出一个长度为N的序列,求$Max{ (a_i + a_j) ⊕ a_k }$ (i,j,k均不相同)  ($N leq 1000$)

    解题思路

      既然$O(n^3)$不行,就考虑$O(n^2 log n)$的做法。

      网上说得很对,凡是和xor有关的80%都是Trie……

      将所有数的二进制建立Trie树,枚举$i,j$——此时在trie树中删去$a_i, a_j$,然后用上一篇文章的方法求得最大的异或。

      那么这道题的关键问题就在于如何删去$a_i, a_j$?每次重新建树显然又$O(n^3)$了(还不止)。

      考虑维护一个cnt数组,代表每个节点出现的次数。每一次删去的时候就像插入一样走一遍把对应节点的cnt减掉,然后在query的时候判定只能访问cnt>0的。这样很方便地处理好了问题

    Code

      数组要清零

    /*By DennyQi*/
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    #define  r  read()
    #define  Max(a,b)  (((a)>(b)) ? (a) : (b))
    #define  Min(a,b)  (((a)<(b)) ? (a) : (b))
    using namespace std;
    typedef long long ll;
    const int MAXN = 32010;
    const int INF = 1061109567;
    inline int read(){
        int x = 0; int w = 1; register int c = getchar();
        while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
        if(c == '-') w = -1, c = getchar();
        while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar(); return x * w;
    }
    int T,N;
    int a[1010],ch[MAXN][2],cnt[MAXN],End[MAXN],num_node;
    bool b[35];
    inline void Convert(int x){
        memset(b, 0, sizeof(b));
        for(int i = 33; x > 0; --i){
            b[i] = x%2;
            x >>= 1;
        }
    }
    inline void Insert(int x){
        Convert(x);
        int u=0;
        for(int i = 1; i <= 33; ++i){
            if(!ch[u][b[i]]){
                ch[u][b[i]] = ++num_node;
            }
            u = ch[u][b[i]];
            ++cnt[u];
        }
        End[u] = x;
    }
    inline void Clear(int x){
        Convert(x);
        int u=0;
        for(int i = 1; i <= 33; ++i){
            u = ch[u][b[i]];
            --cnt[u];
        }
    }
    inline void Add(int x){
        Convert(x);
        int u=0;
        for(int i = 1; i <= 33; ++i){
            u = ch[u][b[i]];
            ++cnt[u];
        }
    }
    inline int Query(int k){
        Convert(k);
        int u = 0;
        for(int i = 1; i <= 33; ++i){
            if(!cnt[ch[u][!b[i]]]){
                u = ch[u][b[i]];
            }
            else{
                u = ch[u][!b[i]];
            }
        }
        return (k^End[u]);
    }
    inline void Init(){
        memset(ch,0,sizeof(ch));
        memset(cnt,0,sizeof(cnt));
        memset(End,0,sizeof(End));
        num_node = 0;
    }
    int main(){
        T=r;
        while(T--){
            Init();
            N=r;
            for(int i = 1; i <= N; ++i){
                a[i]=r;
                Insert(a[i]);
            }
            int ans = -1;
            for(int i = 1; i < N; ++i){
                for(int j = i+1; j <= N; ++j){
                    Clear(a[i]);
                    Clear(a[j]);
                    ans = Max(ans, Query(a[i]+a[j]));
                    Add(a[i]);
                    Add(a[j]);
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    7、NFC技术:让Android自动运行程序
    6、Android中的NFC技术
    5、NFC概述
    Delphi XE7中开发安卓程序一些有用的帮助资源
    Delphi开发安卓程序的感受
    Tomcat绿色版启动"startup.bat"一闪问题的解决方法!
    Delphi判断字符串中是否包含汉字,并返回汉字位置
    Delphi的DLL里如何实现定时器功能?
    Delphi的DLL里如何实现定时器功能?
    VS2013如何添加LIb库及头文件的步骤
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9425459.html
Copyright © 2020-2023  润新知