HDU 1556 Color the ball(线段树:区间更新)

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

题意:

N个气球,每次[a,b]之间的气球涂一次色,统计每个气球涂色的次数。

思路:

这道题目用树状数组和线段树都可以,拿这道题来入门一下线段树的区间更新。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int maxn = 1000000 + 5;
 7 
 8 int n;
 9 int ans[maxn];
10 
11 struct node
12 {
13     int l, r;
14     int n;
15 }t[maxn];
16 
17 int a[maxn];
18 
19 void build(int l, int r, int o)
20 {
21     t[o].l = l;
22     t[o].r = r;
23     t[o].n = 0;
24     if (l == r) return;
25     int mid = (l + r) / 2;
26     build(l, mid, 2 * o);
27     build(mid + 1, r, 2 * o + 1);
28 }
29 
30 
31 void update(int l, int r, int o)
32 {
33     if (t[o].l == l && t[o].r == r)
34     {
35         t[o].n++;
36         return;
37     }
38     int mid = (t[o].l + t[o].r) / 2;
39     if (r <= mid)   update(l, r, 2 * o);
40     else if (l > mid)    update(l, r, 2 * o + 1);
41     else
42     {
43         update(l, mid, 2 * o);
44         update(mid + 1, r, 2 * o + 1);
45     }
46 }
47 
48 void add(int o)
49 {
50     for (int i = t[o].l; i <= t[o].r; i++)
51     {
52         ans[i] += t[o].n;
53     }
54     if (t[o].l == t[o].r)  return;
55     add(2 * o);
56     add(2 * o + 1);
57 }
58 
59 int main()
60 {
61     //freopen("D:\txt.txt", "r", stdin);
62     int x, y;
63     while (~scanf("%d", &n) , n)
64     {
65         memset(ans, 0, sizeof(ans));
66         build(1, n, 1);
67         for (int i = 1; i <= n; i++)
68         {
69             scanf("%d%d", &x, &y);
70             update(x, y, 1);
71         }
72         add(1);
73         for (int i = 1; i <= n-1; i++)
74             cout << ans[i] << " ";
75         cout << ans[n] << endl;
76     }
77 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6556878.html