• lintcode-206-区间求和 I


    206-区间求和 I

    给定一个整数数组(下标由 0 到 n-1,其中 n 表示数组的规模),以及一个查询列表。每一个查询列表有两个整数 [start, end] 。 对于每个查询,计算出数组中从下标 start 到 end 之间的数的总和,并返回在结果列表中。

    注意事项

    在做此题前,建议先完成以下三题:线段树的构造, 线段树的查询,以及线段树的修改。

    样例

    对于数组 [1,2,7,8,5],查询[(1,2),(0,4),(2,4)], 返回 [9,23,20]

    挑战

    O(logN) time for each query

    标签

    二分法 LintCode 版权所有 线段树

    思路

    这里需要用上 lintcode-201-线段树的构造lintcode-202-线段树的查询,不过需要注意的是,这里求得是最小值,所以需要将线段树代码略作修改,原先 SegmentTreeNode 类中的 max 修改为 sum 变量,表示的是在区间 [start, end] 的最元素之和

    code

    /**
     * Definition of Interval:
     * classs Interval {
     *     int start, end;
     *     Interval(int start, int end) {
     *         this->start = start;
     *         this->end = end;
     *     }
     */
    
    class SegmentTreeNode2 {
    public:
        int start, end;
        long long sum;
        SegmentTreeNode2 *left, *right;
        SegmentTreeNode2(int start, int end, long long sum) {
            this->start = start;
            this->end = end;
            this->sum = sum;
            this->left = this->right = NULL;
        }
    };
    
    class Solution {
    public:
        /*
         * @param A: An integer array.
         * @param queries: A query list.
         * @return: The result list.
         */
        vector<long long> intervalSum(vector<int> &A, vector<Interval> &queries) {
            // write your code here
            if (A.empty() || queries.empty()) {
                return vector<long long>();
            }
    
            vector<long long> result;
            SegmentTreeNode2 * root = build(0, A.size() - 1, A);
            for (int i = 0; i < queries.size(); i++) {
                result.push_back(query(root, queries[i].start, queries[i].end));
            }
            return result;
        }
    
        SegmentTreeNode2 * build(int start, int end, vector<int> &nums) {
            // write your code here
            if (start > end) {
                return nullptr;
            }
            SegmentTreeNode2 *root = new SegmentTreeNode2(start, end, 0);
            if (start != end) {
                root->left = build(start, (start + end) / 2, nums);
                root->right = build((start + end) / 2 + 1, end, nums);
                root->sum = root->left->sum + root->right->sum;
            }
            else {
                root->sum = nums[start];
            }
            return root;
        }
    
        long long  query(SegmentTreeNode2 *root, int start, int end) {
            // write your code here
            int mid = (root->start + root->end) / 2;
            if (start <= root->start && end >= root->end) {
                return root->sum;
            }
            else if (mid < start) {
                return query(root->right, start, end);
            }
            else if (mid + 1 > end) {
                return query(root->left, start, end);
            }
            else {
                return query(root->left, start, mid) + query(root->right, mid + 1, end);
            }
        }
    };
    
  • 相关阅读:
    杜教筛刷题总结
    后缀自动机刷题总结
    回文自动机刷题总结
    后缀数组刷题总结
    LCT刷题总结
    省选模拟一题解
    FFT/NTT中档题总结
    二项式反演总结
    JS只能输入数字,数字和字母等的正则表达式
    jquery 条件搜索某个标签下的子标签
  • 原文地址:https://www.cnblogs.com/libaoquan/p/7306239.html
Copyright © 2020-2023  润新知