首页 > 其他 > 详细

【CODEVS1191】数轴染色

时间:2016-01-06 21:56:59      阅读:238      评论:0      收藏:0      [点我收藏+]
  • 题目描述 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<iostream>
#include<cstdio>
using namespace std;
int sum,tot=0;
struct treetype
{
    int Left,Right; //区间[Left,Right) 
    int lptr,rptr; //左右孩子指针 
    int sum; //区间和 
    int bj; //标记 
}t[2000000];
void buildtree(int ll,int rr)
{
    int cur=++tot;
    t[cur].Left=ll; t[cur].Right=rr;
    if(ll!=rr-1)
    {
        t[cur].lptr=tot+1;
        buildtree(ll,(ll+rr)/2);
        t[cur].rptr=tot+1;
        buildtree(+(ll+rr)/2,rr);
        t[cur].sum=t[t[cur].lptr].sum+t[t[cur].rptr].sum;
    }else t[cur].sum=1;
}
void update(int k) //延迟信息下传 
{
    t[t[k].lptr].sum=0; t[t[k].rptr].sum=0; //左右子区间清空 
    t[t[k].lptr].bj=1; t[t[k].rptr].bj=1; //传递标志 
    t[k].bj=0; //清除标志 
}

void change(int k,int ll,int rr) //修改区间[ll,rr)元素的值 
{
    if (ll<=t[k].Left&&rr>=t[k].Right) //覆盖当前区间 
    {
        t[k].sum=0; //区间和=0 
        t[k].bj=1; //设标志 
    }
    else
    {
        if(t[k].bj) update(k); //传递修改 
        if (ll<(t[k].Left+t[k].Right)/2) //修改左区间 
            change(t[k].lptr,ll,rr);
        if (rr>(t[k].Left+t[k].Right)/2) //修改右区间 
            change(t[k].rptr,ll,rr);
        t[k].sum=t[t[k].lptr].sum+t[t[k].rptr].sum; //更新区间和 
    }
}

int query(int k,int ll,int rr) //查询[ll,rr)区间和 
{
    if (ll<=t[k].Left&&rr>=t[k].Right) return t[k].sum;
    if (t[k].bj) update(k); //传递修改 
    int ans=0;
    if (ll<(t[k].Left+t[k].Right)/2) ans+=query(t[k].lptr,ll,rr);
    if (rr>(t[k].Left+t[k].Right)/2) ans+=query(t[k].rptr,ll,rr);
    return ans;
}

int main()
{
    int n,tim,x,y;
    scanf("%d%d",&n,&tim);
    sum=n;
    buildtree(1,n+1);
    for (int i=1;i<=tim;i++)
    {
        scanf("%d%d",&x,&y);
        change(1,x,y+1);
        printf("%d\n",query(1,1,n+1));
    }
    return 0;
}

 

【CODEVS1191】数轴染色

原文:http://www.cnblogs.com/liumengyue/p/5107358.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!