AcWing 802. 区间和
题目
假定有一个无限长的数轴,数轴上每个坐标上的数都是 \(0\)。
现在,我们首先进行 \(n\) 次操作,每次操作将某一位置 \(x\) 上的数加 \(c\)。
接下来,进行 \(m\) 次询问,每个询问包含两个整数 \(l\) 和 \(r\),你需要求出在区间 \([l, r]\) 之间的所有数的和。
输入格式
第一行包含两个整数 \(n\) 和 \(m\)。
接下来 \(n\) 行,每行包含两个整数 \(x\) 和 \(c\)。
再接下来 \(m\) 行,每行包含两个整数 \(l\) 和 \(r\)。
输出格式
共 \(m\) 行,每行输出一个询问中所求的区间内数字和。
数据范围
\(-10^9 \le x \le 10^9\),
\(1 \le n,m \le 10^5\),
\(-10^9 \le l \le r \le 10^9\),
\(-10000 \le c \le 10000\)
输入样例:
3 3
1 2
3 6
7 5
1 3
4 6
7 8
输出样例:
8
0
5
题解
C++ 代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII; //给可存储两个数据的数据类型 pair<int, int> 起别名 PII
const int N = 3e5 + 10; //n次插入(使用l和r两个坐标)和m次查询(使用x一个坐标)相关数据量的上界 一个坐标数据上限是1e5
int n, m;
int a[N], s[N]; //a[]存储做表插入的值 s[]存储a[]前缀和
vector<int> alls; //存储(所有与插入和查询有关的)坐标
vector<PII> add, query; ////存储插入和询问操作的数据
int find(int x) //运用二分的思想 返回的是输入的原坐标x的离散化下标
{ //其实质是将一个很大的数据范围映射到从l到r = alls.size - 1 的一个小区间内
int l = 0, r = alls.size() - 1; //由于所有用到的下标个数就是插入和询问的次数 所以远小于原来全部坐标的数据范围 离散化的本质就是只需处理排序我们需要用到的坐标
while (l < r)
{
int mid = l + r >> 1;
if (alls[mid] >= x) r = mid; //alls[mid]是原坐标 mid是原坐标在数组中的位置 例如原坐标1 3 5 7 9 在数组中的位置是1 2 3 4 5,根据数组中的位置可形成索引,从而映射出新坐标
else l = mid + 1;
}
return r + 1; //确保离散化下标的值从1开始
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ )
{
int x, c;
scanf("%d%d", &x, &c);
add.push_back({x, c}); //记录插入的原坐标和值
alls.push_back(x); //记录插入的原坐标
}
for (int i = 0; i < m; i ++ )
{
int l, r;
scanf("%d%d", &l, &r);
query.push_back({l, r}); //记录询问的坐标l和r
alls.push_back(l);
alls.push_back(r); //分别记录坐标,alls一次只能存一个
}
sort(alls.begin(), alls.end()); //排序
alls.erase(unique(alls.begin(), alls.end()), alls.end()); //去重
for (auto item : add) //执行前n次插入操作
{
int x = find(item.first); //item.first 是add存储的第一个元素即x 原坐标 ,x = find(x)将其转化为离散化下标
a[x] += item.second; //item.second 是add存储的第二个元素即c 此时执行插入数据的操作
}
for (int i = 1; i <= alls.size() ; i ++ ) s[i] = s[i - 1] + a[i]; //预处理前缀和
for (auto item : query) //执行m次询问操作
{
int l = find(item.first);
int r = find(item.second);
cout << s[r] - s[l - 1] << endl;
}
return 0;
}

浙公网安备 33010602011771号