【Trie 字典树】Nikitosh and xor(01字典树)

【Trie 字典树】Nikitosh and xor

时间限制: 1 Sec  内存限制: 128 MB
提交: 4  解决: 2

 

题目描述

Nikitosh the painter has a 1-indexed array A of N elements. He wants to find the maximum value of expression 

(A[l1] ⊕ A[l1 + 1] ⊕ … ⊕ A[r1]) + (A[l2] ⊕ A[l2 + 1] ⊕ … ⊕ A[r2]) where 1 ≤ l1 ≤ r1 < l2 ≤ r2 ≤ N.

Here, x ⊕ y means the bitwise XOR of x and y.

Because Nikitosh is a painter and not a mathematician, you need to help him in this task.

输入

The first line contains one integer N, denoting the number of elements in the array.

The second line contains N space-separated integers, denoting A1, A2, … , AN.

输出

Output a single integer denoting the maximum possible value of the given expression.

样例输入

5
1 2 3 1 2

样例输出

6

提示

2 ≤ N ≤ 4*105
0 ≤ Ai ≤ 109

题目大意:给你n个数字,让你求两段互不交叉的序列分别的亦或和之和的最大值

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 4e5 + 5;
int trie[maxn * 30][2];
int tot = 1;
ll poww[40];
ll l[maxn],r[maxn];
ll zz[maxn];
void insert(ll p)
{
    int tmp = 1;
    for (int i = 30; i >= 0; --i)
    {
        int tmpp;
        if (p & poww[i])
            tmpp = 1;
        else
            tmpp = 0;
        if (!trie[tmp][tmpp])
            trie[tmp][tmpp] = ++tot;
        tmp = trie[tmp][tmpp];
    }
}
ll findd(ll p)
{
    int tmp = 1;
    ll ans = 0;
    for (int i = 30; i >= 0; --i)
    {
        int tmpp;
        if (p & poww[i])
            tmpp = 1;
        else
            tmpp = 0;
        if (trie[tmp][tmpp ^ 1])
        {
            ans += poww[i];
            tmp = trie[tmp][tmpp ^ 1];
        }
        else
            tmp = trie[tmp][tmpp];
    }
    return ans;
}
void init()
{
    poww[0] = 1;
    for (int i = 1; i <= 30; ++i)
        poww[i] = poww[i - 1] << 1;
}
int main()
{
//    freopen("in.txt", "r", stdin);
    int n;
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
    {
        ll tmp;
        scanf("%lld", &tmp);
        zz[i] = tmp ^ zz[i - 1];
    }
    insert(0);
    for (int i = 1; i <= n; ++i)
    {
        l[i] = max(l[i - 1], findd(zz[i]));
        insert(zz[i]);
    }   //从左往右插入字典树
    memset(trie, 0, sizeof(trie));
    tot = 1;
    for (int i = n; i > 0; --i)
    {
        r[i] = max(r[i + 1], findd(zz[i]));
        insert(zz[i]);
    } ////从右往左插入字典树
    ll ans = 0;
    for (int i = 1; i <= n; ++i)
        ans = max(ans, l[i] + r[i]);
    printf("%lld\n", ans);
    return 0;
}

 

    原文作者:Trie树
    原文地址: https://blog.csdn.net/lingyan_BVB/article/details/82854000
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞