zoukankan      html  css  js  c++  java
  • hdu 1556 Color the ball(树状数组)

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

    题意:N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数[a,b]之间的气球染一次色,最后问每个气球染了多少种颜色。

    分析:这是树状数组的第二种应用,区间成段更新,然后求某点的值。

    update(x,num)表示x位置的值增加num,sum(x)表示求1到x的和。

    更新[l,r]区间时,

    先update(l,k),然后update(r+1,-k),就会导致sum(l)到sum(r)的值均增加了k,然后[1,l)和(r,max)这两个范围内的sum都不变,这样sum(x)就是x这个点当前的值了。

    在纸上自己画一画,模拟一下就能明白了。

    AC代码如下:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #define N 100010
     4 int d[N],n;
     5 int lowbit(int x)
     6 {
     7     return x&(-x);
     8 }
     9 void update(int x,int num)
    10 {
    11     while(x<=n)
    12     {
    13         d[x]+=num;
    14         x+=lowbit(x);
    15     }
    16 }
    17 int GetSum(int x)
    18 {
    19     int s=0;
    20     while(x>0)
    21     {
    22         s+=d[x];
    23         x-=lowbit(x);
    24     }
    25     return s;
    26 }  
    27 int main()
    28 {
    29     int i,a,b;
    30     while(scanf("%d",&n)&&n)
    31     {
    32         memset(d,0,sizeof(d));
    33         for(i=0;i<n;i++)
    34         {
    35             scanf("%d%d",&a,&b);
    36             update(a,1);
    37             update(b+1,-1);
    38         }
    39         for(i=1;i<n;i++)
    40             printf("%d ",GetSum(i));
    41         printf("%d
    ",GetSum(n));
    42     }
    43     return 0;
    44 }
    View Code

    上面的方法是树状数组最基本的向上修改,向下统计的形式,其实还可以向上统计,向下修改

    树状数组中的每个节点都代表了一段线段区间,每次更新的时候,根据树状数组的特性可以把b以前包含的所有区间都找出来,然后b以前的

    区间全加一次染色次数然后,再把a以前的区间全部减一次染色次数,这样就修改了树状数组中的[a,b]的区间染色次数,查询每一个点总的染色

    数的时候,就可以直接向上统计每个父节点的值,就是包含这个点的所有区间被染色次数,这就是树状数组中向下查询,向上统计的典型应用

    这样的话update()和sum()的代码就需要修改了,详见代码。

    AC代码如下:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #define N 100010
     4 int d[N],n;
     5 int lowbit(int x)
     6 {
     7     return x&(-x);
     8 }
     9 void update(int x,int num)
    10 {
    11     while(x>0)
    12     {
    13         d[x]+=num;
    14         x-=lowbit(x);
    15     }
    16 }
    17 int sum(int x)
    18 {
    19     int s=0;
    20     while(x<=n)
    21     {
    22         s+=d[x];
    23         x+=lowbit(x);
    24     }
    25     return s;
    26 }
    27 int main()
    28 {
    29     int i,a,b;
    30     while(scanf("%d",&n)&&n)
    31     {
    32         memset(d,0,sizeof(d));
    33         for(i=0;i<n;i++)
    34         {
    35             scanf("%d%d",&a,&b);
    36             update(a-1,-1);
    37             update(b,1);
    38         }
    39         for(i=1;i<n;i++)
    40             printf("%d ",sum(i));
    41         printf("%d
    ",sum(n));
    42     }
    43     return 0;
    44 }
    View Code
  • 相关阅读:
    本地Springboot项目打包成docker镜像并上传到云仓库的全流程
    vue 组件开发到发布到npm全流程
    Python创建文件
    Ngrinder脚本开发各细节锦集(groovy)
    Ngrinder多接口的混合场景压测比例设定方案
    Pycahrm出现推送失败的处理方案,出现Push failed: Failed with error: Authentication failed for 'https://gitee.com/fxcity/Temporary_Test.git/'
    接口测试提取csrf_token和session
    Postman提取html返回值
    HttpRunnerManager自动化测试安装部署(CentOS)
    【转载】centos下搭建RabbitMQ
  • 原文地址:https://www.cnblogs.com/frog112111/p/3263557.html
Copyright © 2011-2022 走看看