字典树

最大异或和

题目描述
image
image

参考题解

前缀和 + 字典树

#include <iostream>
#include <cstdio>

using namespace std;

const int N = 1e5+5, M = N*31;

int n, m;
int sum[N];

int son[M][2], cnt[M], idx;

//v==1: 添加   v==-1: 减少
void insert(int x, int v)
{
    int p = 0;
    for(int i = 30; i >= 0; -- i)
    {
        int bit = x>>i&1;
        if(!son[p][bit])
        {
            son[p][bit] = ++ idx;
        }
        p = son[p][bit];
        cnt[p] += v;
    }
}

//返回亦或结果
int find(int x)
{
    int p = 0, ans = 0;
    for(int i = 30; i >= 0; -- i)
    {
        int bit = x>>i&1;
        if(cnt[son[p][!bit]])
        {
            p = son[p][!bit];
            ans = ans*2+1;
        }
        else
        {
            p = son[p][bit];
            ans = ans*2;
        }
    }
    return ans;
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; ++ i)
    {
        scanf("%d", sum+i);
        sum[i] = sum[i] ^ sum[i-1];
    }
    int ans = 0;
    insert(sum[0], 1);
    for(int i = 1; i <= n; ++ i)
    {
        //l~r: len == m+1
        insert(sum[i], 1);
        if(i > m)
        {
            insert(sum[i-m-1], -1);
        }
        ans = max(ans, find(sum[i]));
    }
    cout << ans << endl;
    return 0;
}
posted @ 2021-05-11 20:56  chaosliang  阅读(29)  评论(0)    收藏  举报