【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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章