zoukankan      html  css  js  c++  java
  • hdu 1556 Color the ball(区间修改,单点查询)

    Problem Description

    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

    解题思路:树状数组裸题,还是套模板。此题要求的是区间修改,不是单点修改,只需利用"差分"思想,即从a开始向上加1实现区间[a,n]中每个元素值加1,同时从b+1开始向上减1即可实现区间[b+1,n]中每个元素值减1,这样就可以实现区间[a,b]中每个元素值加1的效果。时间复杂度是O(nlogn)。可以再复习一下模板加深理解:掌握树状数组~彻底入门

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,c[100010];//表示N
     4 int lowbit(int i){//数组下标二进制非0数字
     5     return i & -i;
     6 }
     7 void update(int i,int x)
     8 {
     9     while(i<=n){
    10         c[i]+=x;
    11         i+=lowbit(i);
    12     }
    13 }
    14 int sum(int i)
    15 {
    16     int ret=0;
    17     while(i>0){
    18         ret+=c[i];
    19         i-=lowbit(i);
    20     }
    21     return ret;
    22 }
    23 int main()
    24 {
    25     int a,b;
    26     while(~scanf("%d",&n),n){
    27         memset(c,0,sizeof(c));
    28         for(int i=1;i<=n;i++){
    29             scanf("%d %d",&a,&b);
    30             update(a,1);//a向上加1
    31             update(b+1,-1);//b+1向上减1
    32             //这样就可以实现区间[a,b]每个数加1
    33         }
    34         for(int i=1;i<=n;i++)//单点查询,统计前缀和即可
    35             printf("%d%c",sum(i),i==n?'
    ':' ');
    36     }
    37     return 0;
    38 }
  • 相关阅读:
    代码整洁之道 读书笔记
    AJAX分页带页码
    下拉框绑定数据
    Excel导入导出
    万能分页存储过程
    android 更新uI主线程
    eclipse配置j2ee项目
    java常见错误云集与注意事项
    亚马逊服务器搭建
    常见sql的error解决方法
  • 原文地址:https://www.cnblogs.com/acgoto/p/8588859.html
Copyright © 2011-2022 走看看