洛谷P2574 XOR的艺术

题目

其实跟线段树1,2差不多,唯一需要区别的就是lazy数组及标记下传时候的操作了。

线段树左儿子的个数应该是比右儿子的个数大的。所以我们需要再将区间异或时,一定要搞清楚每个区间的元素有多少个,然后再将该区间元素的0,1个数颠倒一下就好了

#include <bits/stdc++.h>            
#define ll long long                
#define ls l, mid, root << 1        
#define rs mid + 1, r, root << 1 | 1
using namespace std;                
int n, m, ans[800100], a[800100], lazy[800100];//ans表示一个根节点下1的个数 
inline void pushup(int root)
{
    ans[root] = ans[root << 1] + ans[root << 1 | 1];
}
inline void build(int l, int r, int root)
{
    if (l == r)
    {
        ans[root] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(ls), build(rs);
    pushup(root);
}
inline void pushdown(int l, int r, int root)
{
    int mid = (l + r) >> 1;
    int len = r - l + 1;   
    if (lazy[root])       //如果该节点还没有异或1,那就异或 
    {
        lazy[root << 1] ^= 1;
        lazy[root << 1 | 1] ^= 1;
        ans[root << 1] = len - (len >> 1) - ans[root << 1];//当然还需要更新,原root<<1里有len-len>>1个数。 
        ans[root << 1 | 1] = (len >> 1) - ans[root << 1 | 1];
        lazy[root] = 0;
    }
}
void update(int l, int r, int root, int ql, int qr)
{
    int len = r - l + 1;
    if (ql <= l && r <=  qr)
    {
        lazy[root] ^= 1;
        ans[root] = len  - ans[root];
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(l, r, root);
    if (ql <= mid)
    update(ls, ql, qr);
    if (qr >= mid + 1)
    update(rs, ql, qr);
    pushup(root);
}
int query(int l, int r, int root, int ql, int qr)
{
    int res = 0;
    if (ql <= l && r <= qr)
        return ans[root];
    int mid = (l + r) >> 1;
    pushdown(l, r, root);
    if (ql <= mid)
    res += query(ls, ql, qr);
    if (qr >= mid + 1)
    res += query(rs, ql, qr);
    return res;
}
int main()
{
    cout << (5 >> 1);
    return 0; 
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        char c;
        cin >> c;
        a[i] = c - '0';
    }
    build(1, n, 1);
    while (m--)
    {
        int p, l, r;
        cin >> p >> l >> r;
        if (p)
            printf("%d\n", query(1, n, 1, l, r));
        else
            update(1, n, 1, l, r);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/liuwenyao/p/11348451.html
xor