【BZOJ 1230】 开关灯
【题目链接】
https://www.lydsy.com/JudgeOnline/problem.php?id=1230
【算法】
线段树
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 100010 int n,m,l,r,opt; struct Node { int l,r,sum; bool tag; }; class SegmentTree { private : Node Tree[MAXN<<2]; public : inline void build(int index,int l,int r) { int mid; Tree[index].l = l; Tree[index].r = r; Tree[index].sum = 0; Tree[index].tag = false; if (l == r) return; mid = (l + r) >> 1; build(index<<1,l,mid); build(index<<1|1,mid+1,r); } inline void update(int index) { Tree[index].sum = Tree[index<<1].sum + Tree[index<<1|1].sum; } inline void pushdown(int index) { int l = Tree[index].l,r = Tree[index].r; int mid = (l + r) >> 1; if (Tree[index].tag) { Tree[index<<1].sum = mid - l + 1 - Tree[index<<1].sum; Tree[index<<1|1].sum = r - mid - Tree[index<<1|1].sum; Tree[index<<1].tag ^= 1; Tree[index<<1|1].tag ^= 1; Tree[index].tag = false; } } inline void modify(int index,int l,int r) { int mid; if (Tree[index].l == l && Tree[index].r == r) { Tree[index].sum = r - l + 1 - Tree[index].sum; Tree[index].tag ^= 1; return; } else { pushdown(index); mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) modify(index<<1,l,r); else if (mid + 1 <= l) modify(index<<1|1,l,r); else { modify(index<<1,l,mid); modify(index<<1|1,mid+1,r); } update(index); } } inline int query(int index,int l,int r) { int mid; if (Tree[index].l == l && Tree[index].r == r) return Tree[index].sum; else { pushdown(index); mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) return query(index<<1,l,r); else if (mid + 1 <= l) return query(index<<1|1,l,r); else return query(index<<1,l,mid) + query(index<<1|1,mid+1,r); } } } T; int main() { scanf("%d%d",&n,&m); T.build(1,1,n); while (m--) { scanf("%d%d%d",&opt,&l,&r); if (opt == 0) T.modify(1,l,r); else printf("%d\n",T.query(1,l,r)); } return 0; }