http://acm.cs.ecnu.edu.cn/problem.php?problemid=2525
题意:给一排灯操作,0,s, e表示改变编号从s到e的灯的状态,1,s,e表示查询编号s到e的亮的盏数。
线段树,查询区间,更新区间。
#include <stdio.h>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls(p) p << 1
#define rs(p) p << 1 | 1
const int maxn = 100005;
struct tree
{int l,r;int sum;int col;
}t[maxn<<2];
void pushup(int p){t[p].sum = t[ls(p)].sum + t[rs(p)].sum;
}void pushdown(int p){if(t[p].col){t[ls(p)].col ^= 1;t[rs(p)].col ^= 1;t[ls(p)].sum = t[ls(p)].r - t[ls(p)].l + 1 - t[ls(p)].sum;t[rs(p)].sum = t[rs(p)].r - t[rs(p)].l + 1 - t[rs(p)].sum;t[p].col = 0;}
}
void build(int l, int r, int p)
{t[p].l = l;t[p].r = r;t[p].sum = 0;t[p].col = 0;if(l == r)return;int m = (l+r)>>1;build(l,m,ls(p));build(m+1,r,rs(p));
}void update(int p, int L, int R)
{int l = t[p].l;int r = t[p].r;if(L <= l && r <= R){t[p].sum = r - l + 1 - t[p].sum;t[p].col ^= 1;return;}pushdown(p);int m = (l + r) >> 1;if(L <= m)update(ls(p), L, R);if(R > m)update(rs(p), L, R);pushup(p);
}int query(int L,int R,int p) {int l = t[p].l;int r = t[p].r; if (L <= l && r <= R) {return t[p].sum;}pushdown(p);int m = (l + r) >> 1;int ret = 0;if(L <= m)ret += query(L , R , ls(p));if(R > m)ret += query(L , R , rs(p));return ret;
}int main()
{int n,m;while(~scanf("%d%d",&n,&m)){build(1,n,1);while(m --){int op,s,e;scanf("%d%d%d",&op,&s,&e);if(op == 0){update(1, s, e);}else{int ans = query(s,e,1);printf("%d\n",ans);}}}return 0;
}