树状数组的区间异或

24 阅读1分钟

P5057,题目要求支持对一个只有1或0的区间进行区间异或以及单点查询。

不妨考虑一个差分序列,与普通差分的区别就是用异或来代替减法,则一个元素的真实值就是差分序列的异或前缀和。则对于每次更新,我们可以只用更新位置 ll 和位置 r+1r+1 的值,然后对于每次查询,直接查询相应的前缀和即可。

coding:

class fenwick_tree
{
private:
    int n;
    vector<int> bit;

public:
    fenwick_tree(const int n)
    {
        this->n = n;
        bit.resize(n + 1, 0);
    }

    int lowbit(int x)
    {
        return x & (-x);
    }

    void update(int idx)
    {
        while (idx <= n)
        {
            bit[idx] ^= 1;
            idx += lowbit(idx);
        }
    }

    int query(int idx)
    {
        int res = 0;
        while (idx)
        {
            res ^= bit[idx];
            idx -= lowbit(idx);
        }

        return res;
    }

    void update_range(int l, int r)
    {
        update(l);
        update(r + 1);
    }
};