zoukankan      html  css  js  c++  java
  • 【洛谷】【线段树】P1047 校门外的树

    【题目描述:】

    某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。

    由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

    【输入格式:】

    输入文件tree.in的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

    【输出格式:】

    输出文件tree.out包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

    输入样例#1500 3
    150 300
    100 200
    470 471
    输出样例#1298
    输入输出样例

    【算法分析:】

    使用线段树来维护数轴上的点的状态,作为线段树例题虽然水也有些需要注意的地方

    左端点从0开始,建树时叶子节点直接赋成1,

    lazy-tag开成bool型表示这个区间被清零.

    修改(及标记下传)时不必管要加几或减几,直接把区间清零

    由于最后是输出[0, n]的树的数量,直接输出线段树的第一个节点就好,不需要支持查询

    【代码:】

     1 //校门外的树
     2 #include<iostream>
     3 #include<cstdio>
     4 using namespace std;
     5 
     6 const int MAXN = 10000 + 2;
     7 
     8 int n, m;
     9 struct Segment {
    10     int sum;
    11     bool lazy;
    12 }t[MAXN << 2];
    13 
    14 inline int read() {
    15     int x = 0, f = 1; char ch = getchar();
    16     while(ch < '0' || ch > '9') {
    17         if(ch == '-') f = -1;
    18         ch = getchar();
    19     }
    20     while(ch >= '0' && ch <= '9')
    21         x = (x << 3) + (x << 1) + ch - 48, ch = getchar();
    22     return x * f;
    23 }
    24 
    25 void Build(int o, int l, int r) {
    26     if(l == r) t[o].sum = 1;
    27     else {
    28         int mid = (l + r) >> 1;
    29         Build(o << 1, l, mid);
    30         Build(o << 1|1, mid + 1, r);
    31         t[o].sum = t[o << 1].sum + t[o << 1|1].sum;
    32     }
    33 }
    34 inline void down(int o, int len) {
    35     if(!t[o].lazy) return;
    36     t[o << 1].sum = 0;
    37     t[o << 1|1].sum = 0;
    38     t[o << 1].lazy = 1;
    39     t[o << 1|1].lazy = 1;
    40     t[o].lazy = 0;
    41 }
    42 void Update(int o, int l, int r, int ul, int ur) {
    43     if(ul <= l && r <= ur) {
    44         t[o].sum = 0;
    45         t[o].lazy = 1;
    46     }
    47     else {
    48         down(o, r - l + 1);
    49         int mid = (l + r) >> 1;
    50         if(ul <= mid) Update(o << 1, l, mid, ul, ur);
    51         if(ur > mid) Update(o << 1|1, mid + 1, r, ul, ur);
    52         t[o].sum = t[o << 1].sum + t[o << 1|1].sum;
    53     }
    54 }
    55 
    56 int main() {
    57     n = read(), m = read();
    58     Build(1, 0, n);
    59     for(int i = 1; i <= m; ++i) {
    60         int l = read(), r = read();
    61         Update(1, 0, n, l, r);
    62     }
    63     printf("%d
    ", t[1].sum);
    64 }

     

  • 相关阅读:
    MZOJ #72 数字
    MZOJ #71 maple做数学题
    MZOJ #70 FFF团
    luogu 2051 [AHOI2009]中国象棋
    uva 280
    uva 260
    文件的基本处理
    文件的基础
    Turtle库
    π的计算
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9045732.html
Copyright © 2011-2022 走看看