• HDU 1166 敌兵布阵(线段树 or 二叉索引树)


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

    题意:
    第一行一个整数T,表示有T组数据。 
    每组数据第一行一个正整数N(N<=50000),表示敌人有N个工兵营地,接下来有N个正整数,第i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=50)。 
    接下来每行有一条命令,命令有4种形式: 
    (1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30) 
    (2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30); 
    (3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数; 
    (4)End 表示结束,这条命令在每组数据最后出现; 

    思路:

    这道题目用线段树和二叉索引树都是可以做的,给出两种做法。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 
      6 const int maxn = 1 << 20;
      7 
      8 int n;
      9 
     10 struct node
     11 {
     12     int l, r;
     13     int num;
     14 }tree[maxn];
     15 
     16 char s[6];
     17 int ans;
     18 
     19 void build_tree(int l,int r,int k)
     20 {
     21     tree[k].l = l;
     22     tree[k].r = r;
     23     tree[k].num = 0;
     24 
     25     if(l==r)   return;
     26 
     27     int mid = (l + r) / 2;
     28     build_tree(l, mid, 2 * k);
     29     build_tree(mid + 1, r, 2 * k + 1);
     30 }
     31 
     32 void insert(int x, int i, int k)
     33 {
     34     if (tree[k].l == tree[k].r && tree[k].l == i)
     35     {
     36         tree[k].num += x;
     37         return;
     38     }
     39     int mid = (tree[k].l + tree[k].r) / 2;
     40     if (i <= mid)  insert(x, i, 2 * k);
     41     else           insert(x, i, 2 * k + 1);
     42     tree[k].num = tree[2 * k].num + tree[2 * k + 1].num;
     43 }
     44 
     45 
     46 void search(int l,int r,int k)
     47 {
     48     if (tree[k].l == l && tree[k].r == r)
     49     {
     50         ans += tree[k].num;
     51         return;
     52     }
     53     int mid = (tree[k].l + tree[k].r) / 2;
     54     if (r <= mid)      search(l, r, 2 * k);
     55     else if(l > mid)   search(l, r, 2 * k + 1);
     56     else
     57     {
     58         search(l, mid, 2 * k);
     59         search(mid + 1, r, 2 * k + 1);
     60     }
     61 }
     62 
     63 int main()
     64 {
     65     //freopen("D:\txt.txt", "r", stdin);
     66     int T;
     67     scanf("%d", &T);
     68     int x, y;
     69     int kase = 0;
     70     while (T--)
     71     {
     72         scanf("%d", &n);
     73         build_tree(1, n, 1);
     74         int a;
     75         for (int i = 1; i <= n; i++)
     76         {
     77             cin >> a;
     78             insert(a, i, 1);
     79         }
     80         printf("Case %d:
    ", ++kase);
     81         while (scanf("%s",&s) && s[0] != 'E')
     82         {
     83             scanf("%d%d", &x, &y);
     84             if (s[0] == 'Q')
     85             {
     86                 ans = 0;
     87                 search(x, y, 1);
     88                 cout << ans << endl;
     89             }
     90             else if (s[0] == 'A')
     91             {
     92                 insert(y, x, 1);
     93             }
     94             else
     95             {
     96                 insert(-y, x, 1);
     97             }
     98         }
     99     }
    100 }
     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 const int maxn = 50000 + 5;
     7 
     8 int c[maxn];
     9 int n;
    10 char s[6];
    11 
    12 int lowbit(int x)
    13 {
    14     return x&-x;
    15 }
    16 
    17 int sum(int x)
    18 {
    19     int num = 0;
    20     while (x > 0)
    21     {
    22         num += c[x];
    23         x -= lowbit(x);
    24     }
    25     return num;
    26 }
    27 
    28 void add(int x, int d)
    29 {
    30     while (x <= n)
    31     {
    32         c[x] += d;
    33         x += lowbit(x);
    34     }
    35 }
    36 
    37 int main()
    38 {
    39     //freopen("D:\txt.txt", "r", stdin);
    40     int T;
    41     scanf("%d", &T);
    42     int x, y;
    43     int kase = 0;
    44     while (T--)
    45     {
    46         memset(c, 0, sizeof(c));
    47         cin >> n;
    48         int a;
    49         for (int i = 1; i <= n; i++)
    50         {
    51             cin >> a;
    52             add(i, a);
    53         }
    54         printf("Case %d:
    ", ++kase);
    55         while (scanf("%s",&s) && s[0] != 'E')
    56         {
    57             scanf("%d%d", &x, &y);
    58             if (s[0] == 'Q')
    59             {
    60                 cout << sum(y) - sum(x - 1) << endl;
    61             }
    62             else if (s[0] == 'A')
    63             {
    64                 add(x, y);
    65             }
    66             else
    67             {
    68                 add(x, -y);
    69             }
    70         }
    71     }
    72 }
  • 相关阅读:
    Bitmap和Drawable浅谈
    自定义圆边图片控件
    JAVA入门到精通-第62讲-复杂查询
    JAVA入门到精通-第61讲-复杂查询
    JAVA入门到精通-第60讲-sqlServer基本查询
    JAVA入门到精通-第58讲-SQLserver数据类型
    JAVA入门到精通-第59讲-sqlServer基本查询
    JAVA入门到精通-第56讲-查询分析器
    JAVA入门到精通-第57讲-SQLserver数据类型
    JAVA入门到精通-第55讲-sql server基本使用
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6544848.html
Copyright © 2020-2023  润新知