• [USACO 6.1.3] Cow XOR


    题目大意

      给出一个序列,求一个连续的子序列的异或和最大.

    题解

      先探究一下异或的性质.

        1.可逆性: A XOR B XOR B = A;

        2.满足结合律: (A XOR B) XOR C = A XOR (B XOR C);

      利用以上两个性质有助于我们解题.

      假设有一序列 A1,A2,A3......An-1,A,可以得到另一序列 B1,B2,B3......Bn-1,Bn ,其中Bi表示A序列前i个元素的异或和.

      所以,要求A序列从i到j的异或和就是Bj-Bi-1.

      用这个结论就可以写一个时间复杂度为O(N2)的算法了.

      再观察一下可发现这一个简单的结论,无论什么进制下,高位往往决定这个数的大小.所以我们需要一种数据结构能够支持我们快速查找最优的位置.

      TRIE树?!可以,这很强势!

      然后按二进制的位存储即可.O(N*20)23333333什么鬼.

      TRIE树如果开数组的话要200w*2,因为是221-1嘛,但开了100w*2就AC了我也没办法啦啦啦啦啦/滑稽.

      详情请看代码.

    代码

    /*
    TASK:cowxor
    LANG:C++
    */
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int MAXN = 100005;
    
    int a[MAXN], b[MAXN], ans, st, ed, n;
    int ch[MAXN * 10][2], node;
    
    void insert(int num)
    {
        int u = 0;
        for (int i = 20; i >= 0; --i)
        {
            int now = ((b[num] >> i) & 1);
            if (ch[u][now]) u = ch[u][now];
            else
            {
                ch[u][now] = ++node;
                u = node;
            }
        }
        ch[u][0] = num;
    }
    
    int findmx(int num)
    {
        int u = 0;
        for (int i = 20; i >= 0; --i)
        {
            int now = ((b[num] >> i) & 1);
            if (ch[u][now ^ 1]) u = ch[u][now ^ 1];
            else u = ch[u][now];
        }
        return ch[u][0];
    }
    
    int main()
    {
        freopen("cowxor.in", "r", stdin);
        freopen("cowxor.out", "w", stdout);
        scanf("%d", &n);
        scanf("%d", &a[0]);
        b[0] = a[0];
        ans = b[0];
        st = ed = 0;
        for (int i = 1; i < n; ++i) scanf("%d", &a[i]), b[i] = a[i] ^ b[i - 1];
        memset(ch, 0, sizeof(ch));
        node = 0;
        insert(0);
        for (int i = 1; i < n; ++i)
        {
            int j = findmx(i);
            if (ans < (b[i] ^ b[j]))
            {
                ans = b[i] ^ b[j];
                st = j + 1;
                ed = i;
            }
            insert(i);
        }
        printf("%d %d %d
    ", ans, st+1, ed+1);
        return 0;
    }
  • 相关阅读:
    vue中添加favicon.ico
    SEO 小技巧汇总
    vue中echarts随窗体变化
    vue加载Element ui地址省市区插件-- element-china-area-data
    Echarts 修改折线的颜色和折线的点的大小方法
    vue中添加swiper轮播插件
    Cannot find module 'object-keys' 的解决办法
    适用于所有页面的基础样式base.css
    git clone时的各种报错汇总
    css mix-blend-mode 颜色滤镜混合模式
  • 原文地址:https://www.cnblogs.com/albert7xie/p/5730565.html
Copyright © 2020-2023  润新知