Acwing 3485. 最大异或和

https://www.acwing.com/problem/content/description/3488/

题意:n个数,在区间长度最长为m的情况下,求最大连续异或值。

思路:连续异或值只要将前缀和存储起来再异或即可。对于限制了区间长度的连续异或值,可以将区间的前缀和放到树中,使用滑动窗口把区间外的前缀和移出去即可。

总结:没注意到前缀异或的性质,在这个滑动窗口内,就算是从0开始的前缀和,也不影响在这个窗口内的前缀值计算。
发现,在存数和删数的时候,用int整数传更好用。

而且好像string和bitset有tle风险。

struct Node{
    array<int, 2> next;
    int cnt;

    Node():cnt(0), next{}{}
};

class Trie{
public:
    Trie():root_(0){
        trie_.resize(1);
    }

    void insert(int x){
        int cur = root_;
        for (int i = 30; i >= 0; --i){
            int p = (x >> i) & 1;
            if (trie_[cur].next[p] == 0){
                trie_[cur].next[p] = (int)trie_.size();
                trie_.emplace_back();
            }
            cur = trie_[cur].next[p];
            trie_[cur].cnt ++;
        }
    }

    void erase(int x){
        int cur = root_;
        for (int i = 30; i >= 0; --i){
            int p = (x >> i) & 1;
            cur = trie_[cur].next[p];
            trie_[cur].cnt --;
        }
    }

    int get(int x){
        int cur = root_;
        int res = 0;
        for (int i = 30; i >= 0; --i){
            int p = (x >> i) & 1;
            if (trie_[cur].next[!p] == 0 && trie_[cur].next[p] == 0){
                break;
            }
            if(trie_[cur].next[!p] && trie_[trie_[cur].next[!p]].cnt > 0){
                res += 1 << i;
                cur = trie_[cur].next[!p];
            }
            else{
                cur = trie_[cur].next[p];
            }
        }
        return res;
    };

private:
    int root_;
    vector<Node> trie_;

};

void solve(){
    int n, m;
    cin >> n >> m;

    vector<int> a(n);
    for (auto& x : a){
        cin >> x;
    }

    vector<int> pref(n + 1);
    for (int i = 0; i < n; ++i){
        pref[i + 1] = pref[i] ^ a[i];
    }

    Trie trie{};
    trie.insert(0);
    int ans = 0;
    for (int i = 1; i <= n; ++i){
        if (i > m){
            trie.erase(pref[i - m - 1]);
        }
        ans = max(ans, trie.get(pref[i]));
        trie.insert(pref[i]);
    }

    cout << ans << endl;
}
posted @ 2024-05-07 14:36  _Yxc  阅读(18)  评论(0)    收藏  举报