线段树(区间更新, 区间查询 ,线段染色)

1191 数轴染色

题目描述 Description

在一条数轴上有N个点,分别是1~N。一开始所有的点都被染成黑色。接着
我们进行M次操作,第i次操作将[Li,Ri]这些点染成白色。请输出每个操作执行后
剩余黑色点的个数。

输入描述 Input Description

输入一行为N和M。下面M行每行两个数Li、Ri

输出描述 Output Description

输出M行,为每次操作后剩余黑色点的个数。

样例输入 Sample Input

10 3
3 3
5 7
2 8

样例输出 Sample Output

9
6
3

数据范围及提示 Data Size & Hint

数据限制
对30%的数据有1<=N<=2000,1<=M<=2000
对100%数据有1<=Li<=Ri<=N<=200000,1<=M<=200000

这道题的lazy和value就不能累加因为这里是标记颜色,而不是求和;

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF  0x3f3f3f3f
#define mod 20191117
#define PI acos(-1)
using namespace std;
typedef long long ll ;
const int N = 200000;
int ans ;
struct node
{
    int l , r , val , la ;
}tree[N*4];

void build(int l , int r , int root)
{
    tree[root].l = l , tree[root].r = r ;
    tree[root].val = 0 , tree[root].la = 0;
    if(l == r)
        return ;
    int mid = (tree[root].r + tree[root].l) >> 1 ;
    build(l , mid , root*2);
    build(mid+1 , r , root*2+1);
}

void push(int root)
{
    tree[root*2].val = tree[root*2].r - tree[root*2].l + 1 ;
    tree[root*2+1].val = tree[root*2+1].r - tree[root*2+1].l +1 ;
    tree[root*2].la = tree[root*2+1].la = 1 ;
    tree[root].la = 0 ;
}

void update(int l , int r , int root)
{
    if(tree[root].l >= l && tree[root].r <= r)
    {
        tree[root].la = 1 ;
        tree[root].val = tree[root].r - tree[root].l + 1 ; //注意这道题不能用+= ,因为1就代表白色,再染一遍也是白色。
        return ;
    }
    if(tree[root].la) push(root);
    int mid = (tree[root].l + tree[root].r ) >> 1 ;
    if(l <= mid)
        update(l , r , root*2);
    if(r > mid)
        update(l , r , root*2+1);
    tree[root].val = tree[root*2].val + tree[root*2+1].val ;
}

void query(int l , int r , int root)
{
    if(tree[root].l >= l && tree[root].r <= r)
    {
        ans += tree[root].val ;
        return ;
    }
}

int main()
{
    int n , m ;
    scanf("%d%d" , &n , &m);
    build(1 , n , 1);
    for(int i = 0 ; i < m ; i++)
    {
        int l , r ;
        scanf("%d%d" , &l , &r);
        update(l , r , 1);
        ans = 0 ;
        query(1 , n , 1);
        printf("%d
" , n - ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/nonames/p/11260163.html