LuoguP2846[USACO08NOV]光开关Light Switching【线段树维护区间异或】By cellur925

题目传送门

题目大意,给你一串灯,按一下开关可以将灯的状态取反(开变成关,关变成开)。维护这个序列的两种操作:询问区间内有多少灯是开着的,区间按灯。


开始想的是分别维护区间内0的数量,1的数量,两个懒标记。后来真正写到维护懒标记的时候却感觉不太可行,因为你并不精确的知道区间内哪里是开着,哪里是关着的。


其实我们本质上就是在维护整个异或序列。因为把每个位置取反,实际上就是在进行异或运算。(0->1,1->0)。这样我们在区间修改的时候,只需要维护区间内1的个数,把它用区间长度减去原来的值便得到新值。而懒标记的维护,直接进行异或运算即可。因为懒标记实际上就是在告诉儿子节点怎么做,传递简单的修改无法维护的信息。所以直接异或即可。

这个问题还有一个加加加加加加强版,bzoj1858,有时间干掉他。

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define maxn 100090 
 4 
 5 using namespace std;
 6 
 7 int n,m;
 8 struct SegmentTree{
 9     int l,r,len;
10     int val,lazy;
11 }t[maxn*4];
12 
13 void build(int p,int l,int r)
14 {
15     t[p].l=l,t[p].r=r,t[p].len=r-l+1;
16     if(l==r)
17         return ;
18     int mid=(l+r)>>1;
19     build(p*2,l,mid);
20     build(p*2+1,mid+1,r);
21 }
22 
23 void update(int p)
24 {
25     if(t[p].l==t[p].r) return ;
26     if(!t[p].lazy) return ;
27     t[p*2].val=t[p*2].len-t[p*2].val;
28     t[p*2+1].val=t[p*2+1].len-t[p*2+1].val;
29     t[p*2].lazy^=1;
30     t[p*2+1].lazy^=1;
31     t[p].lazy=0;
32 }
33 
34 void change(int p,int l,int r)
35 {
36     update(p);
37     if(t[p].l==l&&t[p].r==r)
38     {
39         t[p].lazy^=1;
40         t[p].val=t[p].len-t[p].val;
41         return ;
42     }
43     int mid=(t[p].l+t[p].r)>>1;
44     if(l>mid) change(p*2+1,l,r);
45     else if(r<=mid) change(p*2,l,r);
46     else change(p*2,l,mid),change(p*2+1,mid+1,r);
47     t[p].val=t[p*2].val+t[p*2+1].val;
48 }
49 
50 int ask(int p,int l,int r)
51 {
52     update(p);
53     if(t[p].l==l&&t[p].r==r) return t[p].val;
54     int mid=(t[p].l+t[p].r)>>1;
55     if(l>mid) return ask(p*2+1,l,r);
56     else if(r<=mid) return ask(p*2,l,r);
57     else return ask(p*2,l,mid)+ask(p*2+1,mid+1,r);
58 }
59 
60 int main()
61 {
62     scanf("%d%d",&n,&m);
63     build(1,1,n);
64     for(int i=1;i<=m;i++)
65     {
66         int opt=0,l=0,r=0;
67         scanf("%d%d%d",&opt,&l,&r);
68         if(opt==0)
69             change(1,l,r);
70         else if(opt==1)
71             printf("%d\n",ask(1,l,r));
72     }
73     return 0;
74 }
View Code

猜你喜欢

转载自www.cnblogs.com/nopartyfoucaodong/p/9752356.html
今日推荐