Color the ball 此题这个用的是线段树

来源:互联网 发布:淘宝 手机 描述 模板 编辑:程序博客网 时间:2024/06/17 02:11
N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?Input每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。 当N = 0,输入结束。Output每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。Sample Input31 12 23 331 11 21 30Sample Output1 1 13 2 1
#include<iostream>#include<stdio.h>using namespace std;bool flag;struct node{    int l,r,mark;}tree[100001*4];void build(int l,int r,int i){    tree[i].l=l;    tree[i].r=r;            tree[i].mark=0;    if(l==r)    {        return;    }    int mid=(l+r)/2;    build(l,mid,i*2);    build(mid+1,r,i*2+1);    return;}void down_mark(const int& i){    tree[i*2].mark+=tree[i].mark;    tree[i*2+1].mark+=tree[i].mark;    tree[i].mark=0;}void update(int l,int r,int i){    if(tree[i].l==l&&tree[i].r==r)    {        tree[i].mark++;        return;    }    if(tree[i].mark)    {        down_mark(i);    }    int mid=(tree[i].l+tree[i].r)/2;    if(mid>=r)    {        update(l,r,i*2);    }    else if(mid<l)    {        update(l,r,i*2+1);    }    else    {        update(l,mid,i*2);        update(mid+1,r,i*2+1);    }}void query(int l,int r,int i){    if(l==r)    {        if(flag==0)        printf("%d",tree[i].mark);        else            printf(" %d",tree[i].mark);            flag=1;         return;    }    if(tree[i].mark)        down_mark(i);    int mid=(l+r)/2;        query(l,mid,i*2);        query(mid+1,r,i*2+1);}int n,a,b; int main (){     while(~scanf("%d",&n),n)     {        flag=0;        build(1,n,1);        for(int i=0;i<n;i++)        {            scanf("%d%d",&a,&b);            update(a,b,1);         }         query(1,n,1);         printf("\n");     }}
原创粉丝点击