Color the ball
题解:终于会区间更新了!!
延迟标记:为了避免直接更新到叶节点,所以对 对应区间的结点 添加一个标记,记录本次更新的信息,不过当更新该结点的子结点时,一定要将
标记传递下去。这也是为什么在查询的时候也要传递标记。
1 #pragma warning(disable:4996) 2 #include <iostream> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #define lson (root<<1) 8 #define rson (root<<1|1) 9 using namespace std; 10 11 const int maxn = 1e5 + 5; 12 13 int n, time; 14 15 struct node { 16 int l; 17 int r; 18 int add; 19 int sum; 20 }Tree[maxn<<2]; 21 22 inline void Pushup(int root) { 23 Tree[root].sum = Tree[lson].sum + Tree[rson].sum; 24 } 25 26 inline void Pushdown(int root) { 27 Tree[lson].add += Tree[root].add; 28 Tree[rson].add += Tree[root].add; 29 Tree[lson].sum += Tree[root].add*(Tree[lson].r - Tree[root].l + 1); 30 Tree[rson].sum += Tree[root].add*(Tree[rson].r - Tree[rson].l + 1); 31 Tree[root].add = 0; 32 } 33 34 void Build(int l, int r, int root) { 35 Tree[root].l = l; 36 Tree[root].r = r; 37 Tree[root].add = 0; 38 if (l == r) { Tree[root].sum = 0; return; } 39 int mid = (l + r) >> 1; 40 Build(l, mid, lson); 41 Build(mid + 1, r, rson); 42 Pushup(root); 43 } 44 45 void Update(int l, int r, int root) { 46 if (l > Tree[root].r || r < Tree[root].l) return; 47 if (l <= Tree[root].l && r >= Tree[root].r) { 48 Tree[root].add += 1; 49 Tree[root].sum += Tree[root].r - Tree[root].l + 1; //~~~~~~~~~~~~~~~一定要在更新标记的时候顺便更新当前结点的sum 50 return; 51 } 52 if (Tree[root].add) Pushdown(root); 53 int mid = (l + r) >> 1; 54 Update(l, r, lson); 55 Update(l, r, rson); 56 Pushup(root); 57 } 58 59 void Query(int root) { 60 if (Tree[root].l == Tree[root].r) { 61 time++; 62 printf("%d", Tree[root].sum); 63 if (time != n) printf(" "); 64 else printf("\n"); 65 return; 66 } 67 if (Tree[root].add) Pushdown(root); 68 Query(lson); 69 Query(rson); 70 } 71 72 int main() 73 { 74 while (scanf("%d", &n) != EOF && n) { 75 Build(1, n, 1); 76 time = 0; 77 for (int i = 0; i < n; i++) { 78 int a, b; 79 scanf("%d%d", &a, &b); 80 Update(a, b, 1); 81 } 82 Query(1); 83 } 84 return 0; 85 }