zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    .net core下直接执行SQL语句并生成DataTable
    asp.net core获取HttpContext相关操作
    连接Oracle的几种方式
    数据库(表)的逻辑备份与恢复
    Oracle函数
    Oracle 11g ORA-12514:TNS:监听程序当前无法识别连接描述符中请求的服务
    未在本地计算机上注册"MSDAORA.1"提供程序
    如果在安装32位oracle 客户端组件时的情况下以64位模式运行,将出现问题
    Oracle Client安装与基本配置
    事务
  • 原文地址:https://www.cnblogs.com/albert7xie/p/5730565.html
Copyright © 2011-2022 走看看