http://www.zybbs.org/JudgeOnline/problem.php?id=1230
今天下午的多校联合赛就出类似这个题的那个题了 T T 。。都是在区间里进行异或操作。只不过下午那题更恶心,还要输出指定区间里连续的1 。
这个题只需要输出1的数目即可(开着灯的数目)。
下午那个题一直有问题,后来兴海帮我看了,基本知道是哪错了。我总是更新的时候有点迷茫,因为有点纠结什么时候更新自己,什么时候更新子节点。而且,我更新的时候都是在中间更新的,兴海说必须开始就更新,因为下面计算就要用到了。抛弃了以前做hotel看别人做的那种方法,不需要cover标记,直接计算,也很方便。
这个异或操作就是节点记录是否需要异或,然后利用 lazy 思想往子节点传递异或标记,并且更新子节点。
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <string> #include <algorithm> #define MID(x,y) ( ( x + y ) >> 1 ) #define L(x) ( x << 1 ) #define R(x) ( x << 1 | 1 ) #define BUG puts("here!!!") using namespace std; const int MAX = 100010; struct Tnode{ int l,r,sum;bool cover;}; Tnode node[MAX << 4]; void init() { memset(node,0,sizeof(node)); } void Build(int t,int l,int r) { node[t].l = l; node[t].r = r; node[t].cover = 0; if( node[t].l == node[t].r - 1 ) return ; int mid = MID(l,r); Build(L(t),l,mid); Build(R(t),mid,r); } void Updata_len(int t) { node[t].sum = node[t].r - node[t].l - node[t].sum; } void Pushdown(int t) { if( node[t].cover ) { node[L(t)].cover = !node[L(t)].cover; node[R(t)].cover = !node[R(t)].cover; node[t].cover = !node[t].cover; Updata_len(L(t)); Updata_len(R(t)); } } void Updata(int t,int l,int r) { Pushdown(t); if( node[t].l >= l && node[t].r <= r ) { node[t].cover = !node[t].cover; node[t].sum = node[t].r - node[t].l - node[t].sum; return ; } if( node[t].l == node[t].r - 1 ) return ; int mid = MID(node[t].l,node[t].r); if( l >= mid ) Updata(R(t),l,r); else if( r < mid ) Updata(L(t),l,r); else { Updata(L(t),l,mid); Updata(R(t),mid,r); } node[t].sum = node[L(t)].sum + node[R(t)].sum; } int Query(int t,int l,int r) { Pushdown(t); if( node[t].l >= l && node[t].r <= r ) return node[t].sum; if( node[t].l == node[t].r - 1 ) return 0; int mid = MID(node[t].l,node[t].r); int ans = 0; if( l >= mid ) ans = Query(R(t),l,r); else if( r < mid ) ans = Query(L(t),l,r); else ans = Query(L(t),l,mid) + Query(R(t),mid,r); return ans; } int main() { int n,m,ind,x,y; while( ~scanf("%d%d",&n,&m) ) { init(); Build(1,0,n); while( m-- ) { scanf("%d%d%d",&ind,&x,&y); if( ind == 0 ) Updata(1,x-1,y); else { int ans = Query(1,x-1,y); printf("%d\n",ans); } } } return 0; }