codevs 1191 线段树 解题报告

来源:互联网 发布:锐捷网络拓扑图素材 编辑:程序博客网 时间:2024/04/29 12:35

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

思路

题面描述非常简短,给人一种模拟水题的感觉,但是200000的数据还是不可以这样。。。
线段树区间修改就好了。

代码

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#include<vector> using namespace std;const int N=200000+5;int n,m,lf,rt;struct Node{   int lf,rt,val;};Node tree[N*4];void build(int k,int L,int R){    tree[k].lf=L;    tree[k].rt=R;    if (L==R) {tree[k].val=1;return ;}    int mid=(L+R)/2;    build(k*2,L,mid);    build(k*2+1,mid+1,R);    tree[k].val=tree[k*2].val+tree[k*2+1].val;}void change(int k,int L,int R){    int lf,rt,mid;    if (tree[k].val==0) return ;    lf=tree[k].lf;    rt=tree[k].rt;    if (lf==L&&rt==R) {tree[k].val=0;return ;}    mid=(lf+rt)/2;    if (mid>=R) change(k*2,L,R);    else if (mid<L) change(k*2+1,L,R);    else    {        change(k*2,L,mid);        change(k*2+1,mid+1,R);    }    tree[k].val=tree[k*2].val+tree[k*2+1].val;}int main(){    scanf("%d%d",&n,&m);    build(1,1,n);    for (int i=1;i<=m;i++)    {        scanf("%d%d",&lf,&rt);        change(1,lf,rt);        printf("%d\n",tree[1].val);    }    return 0;}
原创粉丝点击