HDOJ-1556 Color the ball

这道题可以用树状数组解决,用到了区间更新,单点求值.设一个数组a(i)表示第i个球被染色的次数,在设一个数组p(i)表示第i个气球染色次数与第i-1个气球染色次数之差。如果要把a到b的气球染一次,则只需p[a]++,p[b+1]–,并且会发现a[i] = b[1] + b[2] +…b[i].此时就可以用树状数组来进行求和.

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <climits>
#include <set>

using namespace std;
#define maxn 100005

int c[maxn], n;
void Update(int m, int p){

    while(m <= n){
        c[m] += p;
        m += m & -m;
    }
}
int Query(int m){

    int sum = 0;
    while(m){
        sum += c[m];
        m -= m & -m;
    }

    return sum;
}
int main(){

// freopen("in.txt", "r", stdin);
    while(cin >> n && n){

        memset(c, 0, sizeof(c));
        for(int i = 1; i <= n; i++){

            int a, b;
            scanf("%d%d", &a, &b);
            Update(a, 1);
            Update(b+1, -1);
        }

        for(int i = 1; i < n; i++)
          printf("%d ", Query(i));
        printf("%d\n", Query(n));
      }

      return 0;
} 

线段树解法:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <climits>
#include <set>

using namespace std;
#define maxn 100005
struct node{
    int l, r, m;
}T[maxn<<2];
int num[maxn<<2];

void Build(int n, int l, int r){

    T[n].l = l;
    T[n].r = r;
    T[n].m = 0;

    if(l == r)
      return ;
    int mid = (l + r) / 2;
    Build(n<<1, l, mid);
    Build(n<<1|1, mid+1, r);
}
void Update(int l, int r, int n, int m){

    if(T[n].l  == l && T[n].r == r){
        T[n].m += m;
        return ;
    }

    int mid = (T[n].l + T[n].r) >> 1;
    if(r <= mid)
       Update(l, r, n<<1, m);
    else if(l > mid)
       Update(l, r, n<<1|1, m);
    else{
        Update(l, mid, n<<1, m);
        Update(mid+1, r, n<<1|1, m);
    } 
}
void Query(int n, int p, int &sum){

    sum += T[n].m; 
    if(T[n].l == T[n].r){
        return ;
    }

    int mid = (T[n].l + T[n].r) >> 1;
    if(p <= mid)
      Query(n<<1, p, sum);
    else 
      Query(n<<1|1, p, sum);
}
int  main(){

// freopen("in.txt", "r", stdin); 
    int n;

    while(cin >> n && n){

        Build(1, 1, n);
        for(int i = 1; i <= n; i++){

            int a, b;
            scanf("%d%d", &a, &b);
            Update(a, b, 1, 1);  
        }
        for(int i = 1; i <= n; i++){

            int sum = 0;
            Query(1, i, sum);
            if(i < n)
              printf("%d ", sum);
            else
             printf("%d\n", sum);
        }
    }
}

你可能感兴趣的:(HDOJ-1556 Color the ball)