【codevs1191】数轴染色 (线段树 区间修改+固定区间查询)

【codevs1191】数轴染色

题目描述 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

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int M = 2e5+10;
int lazy[M<<2],sum[M<<2];
void pushup(int rt){
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

void pushdown(int rt,int m){
    if(lazy[rt]){
        lazy[rt<<1] = 1;
        lazy[rt<<1|1] = 1;
        sum[rt<<1] = 0;
        sum[rt<<1|1] = 0;
        lazy[rt] = 0;
    }
}

void build(int l,int r,int rt){
    lazy[rt] = 0;
    if(l == r){
        sum[rt] = 1;
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt);
}

void update(int L,int R,int l,int r,int rt){
    if(L <= l&&R >= r){
        lazy[rt]=1;
        sum[rt] = 0;
        return;
    }
    pushdown(rt,r-l+1);
    int m = (l + r)>>1;
    if(L <= m) update(L,R,lson);
    if(R > m) update(L,R,rson);
    pushup(rt);
}

int query(int L,int R,int l,int r,int rt){
    if(L <= l&&R >= r){
        return sum[rt];
    }
    pushdown(rt,r-l+1);
    int m = (l + r) >> 1;
    int ret = 0;
    if(L <= m) ret+=query(L,R,lson);
    if(R > m) ret += query(L,R,rson);
    return ret;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,m,x,y;
    cin>>n>>m;
    build(1,n,1);
    while(m--){
        cin>>x>>y;
        update(x,y,1,n,1);
        cout<<query(1,n,1,n,1)<<endl;
    }
}
原文地址:https://www.cnblogs.com/kls123/p/8570295.html