codevs 1191 树轴染色 线段树区间定值,求和

codevs 1191 树轴染色

Time Limit: 1 Sec  Memory Limit: 256 MB

题目连接

http://www.codevs.cn/problem/1191/

Description

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

Input

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

Output


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

Sample Input

10 3
3 3
5 7
2 8

Sample Output

9
6
3

HINT

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

题意

题解:

区间更新,把黑色当成1,白色当成0,然后搞一搞就好了

代码:

#include <stdio.h>
#include <string.h>

const int MAXN = 400000;
int sum[MAXN<<2];
int lazy[MAXN<<2];

void pushup(int rt)
{
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

void pushdown(int rt, int x)
{
    if(lazy[rt] != -1) {
        lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
        sum[rt<<1] = (x-(x>>1))*lazy[rt];///!!!
        sum[rt<<1|1] = (x>>1)*lazy[rt];///!!!
        lazy[rt] = -1;
    }
}

void creat(int l, int r, int rt)
{
    lazy[rt] = -1, sum[rt] = 0;
    if(l == r) return;
    int mid = (l+r)>>1;
    creat(l, mid, rt<<1);
    creat(mid+1, r, rt<<1|1);
    pushup(rt);
}

void modify(int l, int r, int x, int L, int R, int rt)
{
    if(l <= L && r >= R) {
        lazy[rt] = x;
        sum[rt] = x*(R-L+1);///!!!
        return;
    }
    pushdown(rt, R-L+1);///!!!
    int mid = (L+R)>>1;
    if(l <= mid) modify(l, r, x, L, mid, rt<<1);
    if(r > mid) modify(l, r, x, mid+1, R, rt<<1|1);
    pushup(rt);
}

int main()
{
    int i, j, k = 0;
    int n, T, q;
    int x, y, w;
    //while(scanf("%d", &T) != EOF)
    //while(T--)
    //{
        scanf("%d %d", &n, &q);
        creat(1, n, 1);

        while(q--) {
            scanf("%d %d", &x, &y);
            modify(x, y, 1, 1, n, 1);
            printf("%d
",n-sum[1]);
        }

        //printf("Case %d: The total value of the hook is %d.
", ++k, sum[1]);
    //}
    return 0;
}
原文地址:https://www.cnblogs.com/qscqesze/p/4410137.html