zoukankan      html  css  js  c++  java
  • UVALive4682 XOR Sum

    UVALive4682 XOR Sum

    题意

    给定一个数组, 求连续子序列中异或值最大的值.

    题解

    假设答案区间为 [L, R], 则答案为 XOR[L, R], 可以将区间分解为 XOR[L,R] == XOR[0, L - 1] ^ XOR[L, R],

    因此

    1. 不断更新所以数字的 前缀异或和, 将每一个前缀异或和 都 保存到 01Trie
    2. 01Trie 中查询与它 异或值最大 的 前缀异或和
    3. 根据 Step2 的结果, 更新 ans. 重复第一步, 直至无剩余元素.

    需要注意的是, 对于样例中的 3 8 2 6 4 的 前缀异或和分别 为 3 11 9 15 11, 最大值为15, 区间为 [0, 4), 因此每个Trie的初始状态应存在 0.

    AC代码

    #include <cstdio>
    using namespace std;
    int max(int a, int b) {
        return a > b ? a : b;
    }
    struct BinTrie {
        BinTrie* next[2];
        BinTrie() {
            next[0] = next[1] = NULL;
        }
    };
    void insertNum(BinTrie* root, unsigned num) {
        BinTrie* p = root;
        for(int i = 31; i >= 0; i--) {
            int index = (num >> i) & 1;
            if(!p->next[index])
                p->next[index] = new BinTrie();
            p = p->next[index];
        }
    }
    unsigned queryDiff(BinTrie* root, unsigned num) {
        num = ~num;
        BinTrie* p = root;
        unsigned ret = 0;
        for(int i = 31; i >= 0; i--) {
            int index = (num >> i) & 1;
            if(!p->next[index])
                index = 1 - index;
            ret += (index << i);
            p = p->next[index];
        }
        return ret;
    }
    int main() {
        int nTest; scanf("%d", &nTest);
        while(nTest--) {
            int nNum; scanf("%d", &nNum);
            unsigned pre = 0, ans = 0;
            BinTrie* root = new BinTrie();
          	// 保证了 [0, x) 区间的合理性
          	// 否则对于 15 来说, Trie中最大不同的前缀异或和 queryDiff(root, pre) 并不为 0
            insertNum(root, 0);
            while(nNum--) {
                unsigned num; scanf("%u", &num);
                pre = pre ^ num;
                insertNum(root, pre);
                ans = max(ans, queryDiff(root, pre) ^ pre);
            }
            printf("%u
    ", ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    day12_字符连接单引号转意字符
    day12_存储过程说明
    day12_PLSQL编程--存储过程---统一发布动态属性管理
    linux关闭celinux服务
    day11__表管理
    day11_分区表------子分区的母模板(11g)
    day11_分区表------子分区的母模板(10g)
    day11_分区表——分区表常用维护
    smartforms 中的currquan单位处理
    当SVN服务器端IP地址发生变化时,客户端重新定位
  • 原文地址:https://www.cnblogs.com/1pha/p/8721373.html
Copyright © 2011-2022 走看看