首页 > 代码库 > 【HDU1166】敌兵布阵(树状数组或线段树)

【HDU1166】敌兵布阵(树状数组或线段树)

是一道树状数组的裸题,也可以说是线段树的对于单点维护的裸题。多做这种题目可以提高自己对基础知识的理解程度,很经典。

 

 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <numeric> 6 #include <algorithm> 7 #include <cmath> 8 #include <cctype> 9 #include <string>10 using namespace std;11 12 13 const int N = 50005;14 int C[N];15 16 struct peo {17     int x, v;18 }P[N];19 20 int lowbit (int x) {21     return x & -x;22 }23 24 int sum (int x) {25     int ret = 0;26     while (x > 0) {27         ret += C[x]; x -= lowbit(x);28     }29     return ret;30 }31 32 void add (int x, int d) {33     while (x <= 50000) {34         C[x] += d; x += lowbit(x);35     }36 }37 38 int _sum (int d, int u) {39     return sum(u) - sum(d - 1);40 }41 42 int main () {43     int T, n, cur = 0; scanf("%d", &T);44     char op[10];45     while (T --) {46         memset(C, 0, sizeof(C));47         memset(P, 0, sizeof(P));48         scanf("%d", &n);49         for (int i = 0 ; i < n; ++ i) {50             scanf("%d", &P[i].v);51             P[i].x = i + 1;52             add (P[i].x, P[i].v);53         }54         //cout << sum(3) << endl;55         printf("Case %d:\n", ++ cur);56         while (scanf("%s", op)) {57             if (op[0] == E) {58                 break;59             } else if (op[0] == Q) {60                 int x, y;61                 scanf("%d %d", &x, &y);62                 cout << _sum(x, y) << endl;63             } else if (op[0] == S) {64                 int x, y;65                 scanf("%d %d", &x, &y);66                 add (x, -y);67             } else if (op[0] == A) {68                 int x, y;69                 scanf("%d %d", &x, &y);70                 add (x, y);71             }72         }73     }74     return 0;75 }

 

 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cctype> 8 #include <algorithm> 9 #include <numeric>10 11 using namespace std;12 13 struct P{14     int sum, l, r;15 } node[150050];16 17 int n, num[50050] = {0};18 19 void build (int k, int l, int r) {20     node[k].l = l, node[k].r = r;21     if (l == r) {22         node[k].sum = num[l];23     } else {24         build(2 * k, l, (l + r) / 2);25         build(2 * k + 1, ((l + r) / 2) + 1, r);26         node[k].sum = node[2 * k].sum + node[2 * k + 1].sum;27     }28 }29 30 void update(int k, int i, int x) {31     if (node[k].l <= i && node[k].r >= i) {32         node[k].sum += x;33     }34     if (node[k].l == node[k].r) {35         return ;36     }37     if (i <= node[2 * k].r) {38         update(2 * k, i, x);39     }40     else update(2 * k + 1, i, x);41 }42 43 int query (int k, int l, int r) {44     if (l == node[k].l && r == node[k].r) {45         return node[k].sum;46     }47     if (r <= node[2 * k].r)  {48         return query(2 * k, l, r);49     }50     if (l >= node[2 * k + 1].l) {51         return query(2 * k + 1, l, r);52     } else {53         return query(2 * k, l, node[2 * k].r) + query(2 * k + 1, node[2 * k + 1].l, r);54     }55 }56 57 int main(){58     int T;59     scanf("%d",&T);60     for (int z = 1; z <= T; ++ z) {61         memset(num, 0, sizeof(num));62         scanf("%d", &n);63         for (int i = 1; i <= n; ++ i) {64             scanf("%d",&num[i]);65         }66         build(1, 1, n);67         char s[100];68         printf("Case %d:\n",z);69         while (scanf("%s", s)){70             if (s[0] == E)    break;71             if (s[0] == Q){72                 int a, b;73                 scanf("%d%d" ,&a ,&b);74                 printf("%d\n",query(1, a, b));75             }76             if (s[0] == A){77                 int a,x;78                 scanf("%d%d", &a, &x);79                 update(1, a, x);80             }81             if (s[0] == S) {82                 int a,x;83                 scanf("%d%d", &a, &x);84                 update(1, a, -x);85             }86         }87     }88     return 0;89 }

 

【HDU1166】敌兵布阵(树状数组或线段树)