HDOJ1556(树状数组)

来源:互联网 发布:ipad无法加入网络热点 编辑:程序博客网 时间:2024/05/28 05:15

题目

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
31 12 23 331 11 21 30
 

Sample Output
1 1 13 2 1

分析:区间更新及单点求值问题用树状数组。此时query(i)代表原序列中第i个元素的值的变化量。

代码

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;#define MAXN 100005int n, tree[MAXN];int lowbit(int i){return i&(-i);}void update(int i, int x){while (i <= n){tree[i] += x;i = i + lowbit(i);}}int query(int n){int sum = 0;while (n > 0){sum += tree[n];n = n - lowbit(n);}return sum;}int main(){while (scanf("%d", &n) != EOF&&n){memset(tree, 0, sizeof(tree));for (int i = 0; i < n; i++){int a, b;scanf("%d%d", &a, &b);update(a, 1);//a以后元素+1update(b + 1, -1);//b以后元素-1}for (int i = 1; i < n; i++)printf("%d ", query(i));printf("%d\n", query(n));}return 0;}

0 0
原创粉丝点击