zoukankan      html  css  js  c++  java
  • Light Switching(SPOJ LITE)—— 线段树成段更新异或值

      题目连接:http://www.spoj.com/problems/LITE/en/

      题意:有若干个灯泡,每次对一段操作,这一段原先是亮的,就关了;原先是关着的,就打开。询问某一段的打开的灯泡的个数。

      分析:很显然的成段更新,但是一开始想着用某段是不是相同的来维护,敲了很长时间都没有实现。后来经过大力学长知道,对有懒惰标记的节点的亮着的灯泡的和这么更新即可:c[o]=r-l+1-c[o]; 简直奥义!

      另外,从这题可以看出,我对于成段更新的懒惰标记理解不够深刻。应该理解如下:对某点进行pushdown操作时,这点的sum值不更新,更新子节点的sum和add值即可

      具体见代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <set>
     5 #include <iostream>
     6 #define t_mid (l+r>>1)
     7 #define ls (o<<1)
     8 #define rs (o<<1 | 1)
     9 #define lson ls,l,t_mid
    10 #define rson rs,t_mid+1,r
    11 using namespace std;
    12 const int N = 100000 + 5;
    13 
    14 int n,m,c[N<<2];
    15 bool add[N<<2];
    16 void build(int o,int l,int r)
    17 {
    18     c[o]=0,add[o]=0;
    19     if(l==r) return;
    20     build(lson);
    21     build(rson);
    22 }
    23 void pushdown(int o,int len)
    24 {
    25     if(add[o])
    26     {
    27         c[ls]=(len-(len>>1))-c[ls];
    28         c[rs]=(len>>1)-c[rs];
    29         add[ls]^=1;
    30         add[rs]^=1;
    31         add[o]=0;
    32     }
    33 }
    34 void pushup(int o)
    35 {
    36     c[o] = c[ls] + c[rs];
    37 }
    38 void update(int o,int l,int r,int ql,int qr)
    39 {
    40     if(ql<=l && qr>=r)
    41     {
    42         add[o]^=1;
    43         c[o] = r-l+1-c[o];
    44         return;
    45     }
    46     pushdown(o,r-l+1);
    47     if(ql<=t_mid) update(lson,ql,qr);
    48     if(qr>t_mid) update(rson,ql,qr);
    49 
    50     pushup(o);
    51 }
    52 int query(int o,int l,int r,int ql,int qr)
    53 {
    54     if(ql<=l && qr>=r) return c[o];
    55     pushdown(o,r-l+1);
    56     int res = 0;
    57     if(ql<=t_mid) res += query(lson,ql,qr);
    58     if(qr>t_mid) res += query(rson,ql,qr);
    59     return res;
    60 }
    61 
    62 int main()
    63 {
    64     while(scanf("%d%d",&n,&m)==2)
    65     {
    66         build(1,1,n);
    67 
    68         while(m--)
    69         {
    70             int op,x,y;
    71             scanf("%d%d%d",&op,&x,&y);
    72             if(!op) update(1,1,n,x,y);
    73             else printf("%d
    ",query(1,1,n,x,y));
    74         }
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    Leetcode Binary Tree Level Order Traversal
    Leetcode Symmetric Tree
    Leetcode Same Tree
    Leetcode Unique Paths
    Leetcode Populating Next Right Pointers in Each Node
    Leetcode Maximum Depth of Binary Tree
    Leetcode Minimum Path Sum
    Leetcode Merge Two Sorted Lists
    Leetcode Climbing Stairs
    Leetcode Triangle
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5647928.html
Copyright © 2011-2022 走看看