HDU 1166 敌兵布阵 线段树的基本应用——动态区间和问题

题目: http://acm.hdu.edu.cn/showproblem.php?pid=1166

简单题,1A了,这个好像就是传说中的“点树”。

设当前结点表示线段[left, right],编号为i,则结点的左孩子表示线段[left, mid], 编号为2*i,右孩子表示线段[mid+1, right], 编号为2*i+1。

  1 #include <stdio.h>
  2 #include <string.h>
  3 
  4 const int MAXN = 50000;
  5 
  6 //线段树的结点,分别表示一条线段的左端点、右端点、增加的人数
  7 struct Tree_Node
  8 {
  9     int left;
 10     int right;
 11     int num;
 12 }tree[4*MAXN];
 13 
 14 //建立线段树,left和right对应线段树结点中的left和right,i表示当前结点的线段树编号
 15 void build(int left, int right, int i)
 16 {
 17     tree[i].left = left;
 18     tree[i].right = right;
 19     tree[i].num = 0;
 20     if(left == right)
 21     {
 22         return;
 23     }
 24     int mid = (left + right) / 2;
 25     build(left, mid, 2*i);
 26     build(mid+1, right, 2*i+1);
 27 }
 28 
 29 //插入到线段树,tar表示增加人数的那个点在数轴上的编号(不是在线段树上的编号)
 30 //num表示增加的人数,step表示当前结点的线段树编号
 31 void insert(int tar, int num, int step)
 32 {
 33     if(tree[step].left <= tar && tree[step].right >= tar)
 34     {
 35         tree[step].num += num;
 36     }
 37     if(tree[step].left == tree[step].right)
 38     {
 39         return;
 40     }
 41     int mid = (tree[step].left + tree[step].right) / 2;
 42     if(tar <= mid)
 43     {
 44         insert(tar, num, step*2);
 45     }
 46     else
 47     {
 48         insert(tar, num, step*2+1);
 49     }
 50 }
 51 
 52 //left和right表示查询的区间,step表示当前结点的线段树编号
 53 int query(int left, int right, int step)
 54 {
 55     if(tree[step].left == left && tree[step].right == right)
 56     {
 57         return tree[step].num;
 58     }
 59     int mid = (tree[step].left + tree[step].right) / 2;
 60     if(right <= mid)
 61     {
 62         return query(left, right, step*2);
 63     }
 64     else if(left > mid)
 65     {
 66         return query(left, right, step*2+1);
 67     }
 68     else
 69     {
 70         return query(left, mid, step*2) + query(mid+1, right, step*2+1);
 71     }
 72 }
 73 
 74 int main()
 75 {
 76     int t, n, x;
 77     scanf("%d", &t);
 78     for(int item = 1; item <= t; item++)
 79     {
 80         scanf("%d", &n);
 81         build(1, n, 1);
 82         for(int i = 1; i <= n; i++)
 83         {
 84             scanf("%d", &x);
 85             insert(i, x, 1);
 86         }
 87         char cmd[20];
 88         int a, b;
 89         printf("Case %d:
", item);
 90         while(scanf("%s", cmd) != EOF && cmd[0] != 'E')
 91         {
 92             scanf("%d %d", &a, &b);
 93             if(cmd[0] == 'Q')
 94             {
 95                 printf("%d
", query(a, b, 1));
 96             }
 97             else if(cmd[0] == 'A')
 98             {
 99                 insert(a, b, 1);
100             }
101             else if(cmd[0] == 'S')
102             {
103                 insert(a, -b, 1);
104             }
105         }
106     }
107     return 0;
108 }
View Code
原文地址:https://www.cnblogs.com/wolfred7464/p/3394974.html