• acwing802. 区间和


    假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。

    现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。

    接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。

    输入格式

    第一行包含两个整数 n 和 m。

    接下来 n 行,每行包含两个整数 x 和 c。

    再接下来 m 行,每行包含两个整数 l 和 r。

    输出格式

    共 m 行,每行输出一个询问中所求的区间内数字和。

    数据范围

    −10^9≤ x ≤10^9,
    1≤ n,m ≤10^5,
    −10^9≤ l≤r ≤10^9,
    −10000≤ c ≤10000

    输入样例:

    3 3
    1 2
    3 6
    7 5
    1 3
    4 6
    7 8
    

    输出样例:

    8
    0
    5
    

    方法一:

    被难住了..不熟悉C++ STL,故知道离散化和排序但不会去重 23333

    分析:

    1. 数轴是无限长的,所以x∈R,所以不能开个数组并且下标代表x,而输入的x个数是有限的,所以可以将其离散化,比如1 20 100 12312映射到数组下标1 2 3 4
    2. 这题要进行有序的离散化,也就是离散化之后用于映射的数组存储的x是有序的,便于后面使用二分搜索
    3. 最后利用前缀和进行求区间和操作

    做法:

    1. 将输入数据全部读入,alls用来映射 ( 数组下标, x ),即先把所有x读入alls,再用STL函数排序和去重得到正确的映射数据
    2. nums存储每个x上对应的c
    3. 最后前缀和,即区间和

    补充:

    1. find()函数返回大于x的最小元素下标(当x大于最大元素,返回最大元素下标)
    2. 核心在于理解离散化
    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef pair<int, int> PII;
    int n, m;
    int nums[300010];
    
    vector<int> alls;
    vector<PII> add, query;
    
    int find(int x) {
        int l = 0, r = alls.size() - 1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (alls[mid] >= x) r = mid;
            else l = mid + 1;
        }
        return r + 1;
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++) {
            int x, c;
            scanf("%d%d", &x, &c);
            alls.push_back(x);
            add.emplace_back(x, c);
        }
        for (int i = 0; i < m; i++) {
            int l, r;
            scanf("%d%d", &l, &r);
            alls.push_back(l);
            alls.push_back(r);
            query.emplace_back(l, r);
        }
    
        // 排序+去重
        sort(alls.begin(), alls.end());
        alls.erase(unique(alls.begin(), alls.end()), alls.end());
    
        // 处理插入
        for (auto item: add) {
            int x = find(item.first);
            nums[x] += item.second;
        }
    
        // 前缀和
        for (int i = 1; i <= alls.size(); i++) nums[i] += nums[i-1];
    
        for (int i = 0; i < m; i++) {
            int l = find(query[i].first);
            int r = find(query[i].second);
            printf("%d\n", nums[r] - nums[l-1]);
        }
    }
    
  • 相关阅读:
    关于白盒测试的心得
    基于Java的闰年测试
    等价类划分练习的代码实现
    软件测试中的等价类划分练习
    关于软件测试的初学小结
    现代软件工程作业第十二题(原十四题)
    好像木有白盒测试实验的报告,补一个~
    给大家推荐一本书啊啊~
    关于【做一名软件测试工程师,需要具备什么】的我的看法
    关于考试的笔记整理
  • 原文地址:https://www.cnblogs.com/nosae/p/15836080.html
Copyright © 2020-2023  润新知