• 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 }
  • 相关阅读:
    T1-TensorFlow基础
    iOS之开发小技巧
    iOS之自定义控件
    plist文件的读取和xib加载cell
    iOS之tabBar随tableView的滑动而隐藏/显现
    iOS之initialize与load
    iOS之九宫格图片
    iOS之ToolBar定制
    iOS之新浪微博的OAuth授权
    Markdown的简单实用
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5647928.html
Copyright © 2020-2023  润新知