zoukankan      html  css  js  c++  java
  • hdu1166(线段树单点更新、查询)

    题目链接:http://hdu.hustoj.com/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 表示结束,这条命令在每组数据最后出现;
      每组数据最多有40000条命令

    思路:

      典型的线段树单点更新+查询

    代码:

      1 #include <iostream>
      2 using namespace std;
      3 
      4 const int maxn = 50010;
      5 int segTree[maxn * 4];  //1-n子区间数量不超过4*n
      6 
      7 
      8 void pushUp(int root)   //更新父节点值
      9 {
     10     segTree[root] = segTree[root * 2] + segTree[root * 2 + 1];  //这题的操作是求和
     11 }
     12 
     13 void build(int root, int left, int right)  //建立线段树
     14 {
     15     if (left == right) //到了叶子节点就输入叶子结点的值
     16     {
     17         cin >> segTree[root];
     18         return;
     19     }
     20 
     21     int mid = (left + right) / 2;
     22 
     23     //递归建立左子树和右子树
     24     build(root * 2, left, mid);
     25     build(root * 2 + 1, mid + 1, right);
     26 
     27     //每次更新父节点值
     28     pushUp(root);
     29 }
     30 
     31 void update(int root, int p, int add, int left, int right) //单节点更新,p为待更新节点下标,add为需增加或减少的值
     32 {
     33     if (left == right)  //找到单节点就更新
     34     {
     35         segTree[root] += add;
     36         return;
     37     }
     38 
     39     //二分查找指定节点
     40     int mid = (left + right) / 2;
     41     if (p <= mid)
     42     {
     43         update(root * 2, p, add, left, mid);
     44     }
     45     else
     46     {
     47         update(root * 2 + 1, p, add, mid + 1, right);
     48     }
     49 
     50     //每次更新父节点值
     51     pushUp(root);
     52 }
     53 
     54 int query(int root, int q_left, int q_right, int now_left, int now_right)  //查询区间
     55 {
     56     if (q_left <= now_left && q_right >= now_right)  //当前节点区间包含在查询区间内
     57     {
     58         return segTree[root];
     59     }
     60 
     61     int mid = (now_left + now_right) / 2;
     62     int sum = 0;
     63     if (q_left <= mid)
     64     {
     65         sum += query(root * 2, q_left, q_right, now_left, mid);
     66     }
     67     if (q_right > mid)
     68     {
     69         sum += query(root * 2 + 1, q_left, q_right, mid + 1, now_right);
     70     }
     71     return sum;
     72 }
     73 
     74 int main()
     75 {
     76     ios::sync_with_stdio(false);    //取消cin于stdin的同步,不加这句除非用scanf和printf,不然会TLE
     77     int t, n;
     78     char op[10];
     79     cin >> t;
     80     for (int i = 1; i <= t; i++)
     81     {
     82         cout << "Case " << i << ":" << endl;
     83         cin >> n;
     84         build(1, 1, n);
     85         while(cin >> op)
     86         {
     87             if (op[0] == 'E')
     88             {
     89                 break;
     90             }
     91             int a, b;
     92             cin >> a >> b;
     93             if (op[0] == 'Q')   //询问
     94             {
     95                 int ans = query(1, a, b, 1, n);
     96                 cout << ans << endl;
     97             }
     98             else if (op[0] == 'S')  //
     99             {
    100                 update(1, a, -b, 1, n);
    101             }
    102             else if (op[0] == 'A')  //
    103             {
    104                 update(1, a, b, 1, n);
    105             }
    106         }
    107     }
    108     return 0;
    109 }

    体会:

      线段树的入门题,加深对线段树的理解和熟悉一下相关操作的代码编写。

  • 相关阅读:
    [ jquery 选择器 :hidden ] 此方法选取匹配所有不可见元素,或者type为hidden的元素
    剑指 Offer 03. 数组中重复的数字 哈希
    LeetCode 1736. 替换隐藏数字得到的最晚时间 贪心
    Leetcode 1552. 两球之间的磁力 二分
    Leetcode 88. 合并两个有序数组 双指针
    LeetCode 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?
    LeetCode 1743. 相邻元素对还原数组 哈希
    LeetCode 1745. 回文串分割 IV dp
    剑指 Offer 47. 礼物的最大价值 dp
    剑指 Offer 33. 二叉搜索树的后序遍历序列 树的遍历
  • 原文地址:https://www.cnblogs.com/friend-A/p/9365313.html
Copyright © 2011-2022 走看看