PowerOJ 2475 Xor问题

                                                                                                   异或问题

                                                            时间限制:2000 MS内存限制:65536 KB

描述

问题很简单,现在有一个数组a1,a2,a3……an。你的任务就是找到一个连续子段[l,r],使得al^al+1^……^ar达到最大。
 

输入

多组输入,每组有两行。第一行有一个整数n(1<=n<=10^5),表示数组的元素个数。第二行有n个元素,依次表示数组的元素。(0<=ai<=10^6)
 

产量

每组输出一行,这行仅一个数字。表示最大的连续子段异或值。

样本输入

5
1 2 3 4 5
5
2 3 2 3 2

样本输出

7
3
思路:连续子段可以利用前缀和的思想  -- 这里是前缀^  然后利用字典树的思想  注意只有一个数的时候查询前缀 所以先预先加入一个 0
ACcode:
 
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int a[100010], ch[2800000][2], ans, clk;
void insert(int k)
{
    int root = 0;
    for (int i = 25; i >= 0; i--)
    {
        int s = ((1 << i)&k);
        if (s)
        {
            if (ch[root][1] == 0)
            {
                ch[root][1] = ++clk;
                ch[clk][0] = 0;
                ch[clk][1] = 0;
            }
            root = ch[root][1];
        }
        else
        {
            if (ch[root][0] == 0)
            {
                ch[root][0] = ++clk;
                ch[clk][0] = 0;
                ch[clk][1] = 0;
            }
            root = ch[root][0];
        }
    }
}
int quary(int k)
{
    int root = 0, cnt = 0;
    for (int i = 25; i >= 0; i--)
    {
        int s = ((1 << i)&k);
        if (s)
        {
            if (ch[root][0] != 0)
            {
                root = ch[root][0];
            }
            else
            {
                root = ch[root][1];
                cnt += (1 << i);
            }
        }
        else
        {
            if (ch[root][1] != 0)
            {
                root = ch[root][1];
                cnt += (1 << i);
            }
            else
                root = ch[root][0];
        }
    }
    return k^cnt;
}
int main()
{
    int n, x;
    while (scanf("%d", &n) != EOF)
    {
        ans = 0;
        clk = 0;
        ch[0][0] = 0;
        ch[0][1] = 0;
        insert(0);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            a[i] ^= a[i - 1];
            insert(a[i]);
        }
        for (int i = 1; i <= n; i++)
            ans = max(ans, quary(a[i]));
        printf("%d\n", ans);
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值