HDU 1556 Color the ball

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 Input

3 1 1 2 2 3 3 3 1 1 1 2 1 3 0
 

Sample Output

1 1 1 3 2 1
 
 
//成段更新 单点询问
#include <stdio.h>//线段树
#include <stdlib.h>
#include <string.h>
typedef struct node
{
    int l;
    int r;
    int nu;
}LT;
LT lr[400000];
int ctr;
void ct(int l,int r,int k)//线段树的构建
{
    int m=(l+r)>>1;
    lr[k].l=l;
    lr[k].r=r;
    lr[k].nu=0;
    if(l==r)
      return;
    ct(l,m,k<<1);
    ct(m+1,r,k<<1|1);
}
void updata(int i,int j,int k)//更新数据
{
    int m=(lr[k].l+lr[k].r)>>1;
    if(i==lr[k].l&&j==lr[k].r)
          {
              lr[k].nu++;
              return ;
          }
    if(i<=m&&j>m)
       {
           updata(i,m,k<<1);
           updata(m+1,j,k<<1|1);
       }
    else
      if(i>m)
        updata(i,j,k<<1|1);
       else
       updata(i,j,k<<1);
}
void output(int k,int n)//输出
{
       n+=lr[k].nu;
     if(lr[k].l==lr[k].r)
     {
        if(ctr)
         printf(" %d",n);
         else
          printf("%d",n);
          ctr=1;
         return ;
     }
     output(k<<1,n);
     output(k<<1|1,n);
}
int main()
{
   int n,i,a,b;
   while(scanf("%d",&n),n)
   {  ct(1,n,1);
     for(i=0;i<n;i++)
       {
           scanf("%d%d",&a,&b);
           updata(a,b,1);
       }
     ctr=0;
     output(1,0);
     printf("\n");
   }
    return 0;
}
                                                                  -----江财小子
原文地址:https://www.cnblogs.com/372465774y/p/2421704.html