zoukankan      html  css  js  c++  java
  • HDU

    Color the ball

    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 16484    Accepted Submission(s): 8201

    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 1 3 0
     
    Sample Output
    1 1 1 3 2 1
     
    思路:通过这题好好理解了一下树状数组,为什么 sum (i) 可以表示该气球的操作总数,怎么更新,怎么计算,都要好好理解一下。我是这么理解的,首先说一下树状数组的区间更新。比如 [a,b] 区间的更新,我们先从点 a 更新,那么该点之上的所有祖先结点都会被更新(树状数组的原理),抽象到数轴上就是 大于等于 a的区域全部被更新了一次。这时应该发现了吧,b向上的区间被多余更新了,那么我们这是再次更新 b向上的区间,另它的区间操作与之前 a 的相反即可。



    至于sum (i) 为什么可以表示该点的更新次数,应该这么理解,每一次区间更新可以理解为该区间的操作数,它是由 1 - i 这个范围的操作总和决定的(不明白的好好理解一下树状数组的那个图),正好这样也和更新操作对应上了。

    代码如下
    树状数组:
      1 #include <iostream>
      2 #include <cstring>
      3 using namespace std;
      4 
      5 int c[100005];
      6 
      7 int lowbit(int x){
      8     return x & (-x);
      9 }
     10 void add(int id,int p){
     11     while(id <= 100000){
     12         c[id] += p;
     13         id += lowbit(id);
     14     }
     15 }
     16 int sum(int id){
     17     int sum = 0;
     18     while(id >= 1){
     19         sum += c[id];
     20         id -= lowbit(id);
     21     }
     22     return sum;
     23 }
     24 
     25 int main()
     26 {
     27     ios_base::sync_with_stdio(0);
     28     cin.tie(0);
     29 
     30     int n;
     31     while(cin>>n,n != 0){
     32         int x,y;
     33         memset(c,0,sizeof(c));
     34         for(int i = 1;i <= n;i ++){
     35             cin>>x>>y;
     36             add(x,1);       //更新 a 向上的区间 +1
     37             add(y+1,-1);    //更新 b 向上的区间 -1
     38         }
     39         for(int i = 1;i <= n;i ++){
     40             if(i != 1)  cout<<" ";
     41             cout<<sum(i);       //求所有的操作数总和
     42         }
     43         cout<<endl;
     44     }
     45     return 0;
     46 }
     47 
     48 
     49 线段树:
     50 
     51 #include <iostream>
     52 #include <cstring>
     53 #include <cstdio>
     54 #include <cmath>
     55 using namespace std;
     56 
     57 struct Node{
     58     int l,r;
     59     int sum;
     60 }node[400005];
     61 
     62 void build(int id,int l,int r){
     63     node[id].l = l;
     64     node[id].r = r;
     65     node[id].sum = 0;
     66     if(l == r)
     67         return ;
     68 
     69     int mid = (l+r) >> 1;
     70     build(id*2,l,mid);
     71     build(id*2+1,mid+1,r);
     72 }
     73 
     74 void update(int id,int l,int r){
     75     if(node[id].l == l && node[id].r == r){
     76         node[id].sum++;
     77         return ;
     78     }
     79 
     80     int mid = node[id].l+node[id].r >> 1;
     81     if(r <= mid)   update(id*2,l,r);
     82     else if(l > mid)
     83         update(id*2+1,l,r);
     84     else{
     85         update(id*2,l,mid);
     86         update(id*2+1,mid+1,r);
     87     }
     88 }
     89 
     90 int ans;
     91 void query(int id,int temp){
     92     ans += node[id].sum;
     93 
     94     if(node[id].l == node[id].r && node[id].l == temp)
     95         return ;
     96 
     97     int mid = (node[id].l + node[id].r) >> 1;
     98     if(temp <= mid) query(2*id,temp);
     99     else
    100         query(2*id+1,temp);
    101 }
    102 int main()
    103 {
    104     int n;
    105     while(cin>>n,n != 0){
    106         int l,r;
    107         build(1,1,n);
    108         for(int i = 1;i <= n;i ++){
    109             scanf("%d%d",&l,&r);
    110             update(1,l,r);
    111         }
    112         for(int i = 1;i <= n;i ++){
    113             if(i != 1)  cout<<" ";
    114             ans = 0;
    115             query(1,i);
    116             cout<<ans;
    117         }
    118         cout<<endl;
    119     }
    120     return 0;
    121 }
    View Code
  • 相关阅读:
    MySQL优化语句
    Nagios监控mysql的安装配置及报警
    LR,mad
    时序预测 04
    [标点符...] 机器学习算法之XGBoost -什么是XGBoost? -优势&运算流程 -算法原理&数学原理 -一棵树的生成细节 -主要参数介绍
    [标点符] 机器学习算法之Boosting -集成学习的概念扥类 -bagging/boosting/stacking的区别 -boosting算法原理 -AdaBoost/Gradient Boosting/XGBoost简介
    [标点符] 机器学习算法之决策树 学习笔记(1/3) 待续...
    【第17期Datawhale | 零基础入门金融风控-贷款违约预测】Task05:模型融合(3天) : stacking (叠加)+GPU加速示例
    [特征工程01] 什么是归一化?归一化/标准化有什么用?pandas与归一化的简单实践
    【第17期Datawhale | 零基础入门金融风控-贷款违约预测】Task04:建模与调参(3天) : 调参一下记录和结果
  • 原文地址:https://www.cnblogs.com/Jstyle-continue/p/6351928.html
Copyright © 2011-2022 走看看