AcWing1414牛XOR

タイトル説明:

農家のジョンは、牛に餌をやるときに問題に遭遇しました。

彼は合計N頭の牛を飼っています。

各給餌の前に、N頭の牛が1〜Nの順に並んでいます。

さらに、各牛には一意ではない可能性のある整数が割り当てられます。

次に、割り当てられたすべての整数が長さNの整数シーケンスを形成します。

サブシーケンス内の要素のXOR合計を最大化できるように、整数シーケンス内の連続する空でないサブシーケンスを見つけてください

そのようなシーケンスが複数ある場合は、シーケンスの最後にある整数に対応する牛の番号が小さいシーケンスを選択します。

それでも複数の代替シーケンスがある場合は、長さが最も短いものを選択してください。

入力フォーマット

最初の行には整数Nが含まれています。

行2〜N + 1では、各行に整数が含まれ、行iiの整数は、i-1の番号が付けられた牛に割り当てられた整数値を表します。

出力フォーマット

最大のXOR合計を表す3つの整数、選択したシーケンスの最初の整数に対応する牛の番号、および選択したシーケンスの最後の整数に対応する牛の番号をそれぞれ出力します。

データ範囲

1≤N≤10^ 5の場合
、牛に割り当てられる整数の範囲は[0,2 ^ 21-1]です。

入力サンプル:

5
1
0
5
4
2

サンプル出力:

6 4 5
#include <iostream>
#include <cstdio>

using namespace std;
const int MAX = 100009;

int son[MAX * 21][2]; // son[p][u] 表示结点编号为p的u儿子(这个题只有0 1两个儿子)的编号
int n, idx;
int s[MAX], id[MAX * 21];

void insert_trie(int num, int k)
{
    int p = 0;

    for(int i = 20; i >= 0; i--)
    {
        int u = num >> i & 1;
        if(!son[p][u])
            son[p][u] = idx++;
        p = son[p][u];
    }
    id[p] = k;
}

int query(int x)
{
    int p = 0;

    for(int i = 20; i>= 0; i--)
    {
        int u = x >> i & 1;
        if(son[p][!u])
            p = son[p][!u];
        else
            p = son[p][u];
    }
    return id[p];
}

int main()
{
    scanf("%d", &n);

    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &s[i]);
        s[i] = s[i] ^ s[i - 1];
    }

    insert_trie(s[0], 0);

    int maxx = -1, l, r;

    for(int i = 1; i <= n; i++)
    {
        int k = query(s[i]);

        int t = s[i] ^ s[k];
        if(t > maxx)
        {
            maxx = t;
            l = k + 1;
            r = i;
        }
        insert_trie(s[i], i);
    }

    printf("%d %d %d\n", maxx, l, r);

    return 0;
}

 

おすすめ

転載: blog.csdn.net/weixin_44620183/article/details/114059079