hdu 1556 color the ball

来源:互联网 发布:上海网络宣传 编辑:程序博客网 时间:2024/05/16 11:48

 http://acm.hdu.edu.cn/showproblem.php?pid=1556

第一次自己写线段树的代码,一点也没有参照别人的,而且还是1A,激动啊~

题目的意思很简单,就是让你给位置连续的气球涂色,然后n次涂色以后问你每个气球在这个过程中总共涂过多少次颜色,题目比较简单。我的思路是这样的,用每个线段树节

点的value存放以它为父节点的气球总共一起涂过的颜色次数,value的初始值为0,然后n次涂色以后进行一次遍历二叉树,让孩子节点依次与它的父节点的value相加,最后的

叶子节点的值就表示每个气球涂过的颜色次数,放在一个数组visit中,最后将visit数组输出来

 

下面是代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

const int maxn=100002;

struct node
{
   int l,r;
   int v;
}tree[4*maxn];

int visit[maxn];
int n,a,b;

void Creat(int l,int r,int p)
{
   tree[p].l=l;
   tree[p].r=r;
   tree[p].v=0;
   if(l==r) return;
   int mid=tree[p].l+tree[p].r>>1;
   Creat(l,mid,p<<1);
   Creat(mid+1,r,p<<1|1);
}

void update(int a,int b,int p)
{
   if(tree[p].l==a&&tree[p].r==b)
   {
      tree[p].v++;
      return;
   }
   int mid=tree[p].l+tree[p].r>>1;
   if(a>mid) update(a,b,p<<1|1);
   else if(b<=mid) update(a,b,p<<1);
   else
   {
      update(a,mid,p<<1);
      update(mid+1,b,p<<1|1);
   }
}

void get_sum(int p)
{
   if(tree[p].l==tree[p].r)
   {
      visit[tree[p].l]=tree[p].v;
      return;
   }
   tree[p<<1].v+=tree[p].v;
   tree[p<<1|1].v+=tree[p].v;
   get_sum(p<<1);
   get_sum(p<<1|1);
}

int main()
{
   while(scanf("%d",&n),n)
   {
      memset(visit,0,sizeof(visit));
      Creat(1,n,1);
      for(int i=0;i<n;i++)
      {
         scanf("%d%d",&a,&b);
         update(a,b,1);
      }
      get_sum(1);
     
      for(int i=1;i<n;i++)
         printf("%d ",visit[i]);
      printf("%d\n",visit[n]);
   }
  
   return 0;
}