Hrbust 1717最大异或值

最大异或值
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 2468(199 users)Total Accepted: 803(160 users)Rating: Special Judge: No
Description

给一个长度为n的整数序列,现在要你截取这个序列的一个前缀和一个后缀(前缀和后缀不能相交),使得前缀和后缀的异或值最大。

前缀和后缀的异或值为前缀序列中的数和后缀序列中的数,异或的结果,比如,某个序列的前缀为1、 2、 4 ,后缀为8、 16,那么它们的异或值为31.

前缀和后缀可以为空,为空时他们的值为0。
Input

有多组测试数据,请处理到文件结束。

对于每组测试数据,第一行包含一个整数n(1<=n<=100 000)。

接下来一行有n个用空格隔开的整数a1, a2, a3, ..., an (0 <= ai <= 1000 000 000 000)。

Output

对于每组测试数据输出一行,保包含一个整数,表示异或的最大的值。

Sample Input
2
1 2
3
1 2 3
2
1000 1000
Sample Output

331000

题解:求最大异或值,首先考虑01字典树,我们每次将前I项异或和加入树种,查询后i-1项的的最大值,不断更新答案。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define mem(a) memset(a, 0, sizeof(a))
#define eps 1e-5
#define MAX 400030
#define INF 0x3f3f3f3f
//01字典树
//http://blog.csdn.net/qq_33183401/article/details/52263237 加强版
using namespace std;
long long pre[MAX];
long long suf[MAX];
long long a[MAX];
long long dp[MAX];
long long ch[32*MAX][2];
long long val[32*MAX];
long long sz;
void init()
{
    sz=1;
    mem(ch[0]);
}
void Insert(long long a)
{
    long long u=0;
    for(int i=31;i>=0;i--)
    {
        long long c=((a>>i)&1);
        if(!ch[u][c])
         {
             mem(ch[sz]);
             val[sz]=0;
             ch[u][c]=sz++;
         }
         u=ch[u][c];
    }
    val[u]=a;

}
long long query(long long a)
{
    long long u=0;
    for(int i=31;i>=0;i--)
    {
        long long c=((a>>i)&1);
        if(ch[u][c^1])
            u=ch[u][c^1];
        else
            u=ch[u][c];
    }
    return val[u]^a;

}//以上为模板
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF&&n)
    {
    init();
    long long ert=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        ert^=a[i];
    }
    init();
    long long maxn=0;
    Insert(0);
    long long  ins=0,anss=0;
        for(int i=1; i<=n; i++){
            ins^=a[i]; ert^=a[i];
            Insert(ins);
            anss=max(anss,query(ert));
        }

    printf("%lld\n",anss);
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值