USACO 2008 Nov Gold 3.Light Switching 线段树

Code:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 200000 + 4;
int lazy[maxn << 2], sumv[maxn << 2];
inline void pushdown(int o, int l,int r)
{
    int ls = (o << 1), rs = (o << 1)|1, mid = (l + r) >> 1;
    if(lazy[o]) 
    {
        lazy[ls] ^= 1, lazy[rs] ^= 1;
        if(ls)  sumv[ls] = (mid - l + 1) - sumv[ls];
        if(rs)  sumv[rs] = (r - mid) - sumv[rs];
        lazy[o] = 0;
    }
}
inline void pushup(int o){ sumv[o] = sumv[(o << 1)] + sumv[(o << 1)|1]; } 
void update(int l,int r,int L,int R,int o)
{
    if(r < L || l > R || l > r) return ;
    if(l >= L && r <= R)
    {
        lazy[o] ^= 1, sumv[o] = (r - l + 1) - sumv[o];
        return ;
    }
    int mid = (l + r) >> 1, ls = (o<<1), rs = (o<<1)|1;
    pushdown(o, l, r);
    update(l,mid, L,R,ls);
    update(mid + 1, r, L, R ,rs);
    pushup(o);
}
int query(int l,int r, int L,int R,int o)
{
    if(l > r || r < L || l > R) return 0;
    if(l >= L && r <= R) return sumv[o];
    int mid = (l + r) >> 1, ls = (o << 1), rs = (o << 1)|1;
    pushdown(o, l, r);
    int tmp = 0;
    tmp += query(l, mid, L, R, ls);
    tmp += query(mid + 1, r, L, R, rs);
    return tmp;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= m; ++i)
    {
        int ops, a, b;
        scanf("%d%d%d",&ops,&a,&b);
        if(ops == 0)update(1, n, a, b, 1);
        if(ops == 1)printf("%d
", query(1, n, a, b, 1));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/guangheli/p/9845149.html