由于上手就做那种xor和cover混合、第二个就做树型转线性的xor,现在做这个。。。
可谓是给我一个xor的大彻大悟的机会啊!
由于孟神的指导。。。我的线段树,算是基本的入门了。。。
昂。。总结起来有以下几点:
懒惰标记跟本节点无关,因为懒惰标记到本节点之前,已经处理完本届点的值了。
也就是说,在pushdown过程中,要处理子节点的懒惰标记和值。
update到符合要求的节点的时候,要进行懒惰标记,同时处理本节点的值,
而que的时候,直接返回本节点的值就可以了。
而且,懒惰标记只能从上往下推,不能从下往上推。
也就是说,update过程中需要pushup,而que不需要。
最后是代码= = 。。。
#include<stdio.h> #define lson l,mid,rt*2 #define rson mid+1,r,rt*2+1 #define X 100010 int a[X*4],sum[X*4],ll,rr; void pushup(int rt){ sum[rt]=sum[rt*2]+sum[rt*2+1]; } void Xor(int l,int r,int rt){ a[rt]^=1; sum[rt]=r-l+1-sum[rt]; } void pushdown(int l,int r,int rt){ if(a[rt]){ a[rt]=0; int mid=l+r>>1; Xor(lson); Xor(rson); } } void update(int l,int r,int rt){ if(ll<=l&&rr>=r){ Xor(l,r,rt); return ; } pushdown(l,r,rt); int mid=l+r>>1; if(ll<=mid)update(lson); if(rr>mid)update(rson); pushup(rt); } int que(int l,int r,int rt){ if(ll<=l&&rr>=r){ return sum[rt]; } pushdown(l,r,rt); int mid=l+r>>1,as=0; if(ll<=mid)as=que(lson); if(rr>mid)as+=que(rson); return as; } int main(){ int i,j,n,m,f; while(~scanf("%d%d",&n,&m)){ for(i=0;i<=4*n;i++)a[i]=sum[i]=0; for(i=0;i<m;i++){ scanf("%d%d%d",&f,&ll,&rr); if(f)printf("%d\n",que(1,n,1)); else update(1,n,1); } } return 0; }