1.区间和(离散化)
题目描述:
假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。第一行包含两个整数 n 和 m。接下来 n 行,每行包含两个整数 x 和 c。再接下来 m 行,每行包含两个整数 l 和 r。输出共 m 行,每行输出一个询问中所求的区间内数字和。
测试样例:
输入:
3 3
1 2
3 6
7 5
1 3
4 6
7 8
输出:
8
0
5
复制大佬代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 300010;
int n, m;
int a[N], s[N];
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()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
{
int x, c;
cin >> x >> c;
add.push_back({x, c});
alls.push_back(x);
}
for (int i = 0; i < m; i ++ )
{
int l, r;
cin >> l >> r;
query.push_back({l, r});
alls.push_back(l);
alls.push_back(r);
}
// 去重
sort(alls.begin(), alls.end());
alls.erase(unique((alls.begin()), alls.end()),alls.end());
// 处理插入
for (auto item : add)
{
int x = find(item.first);
a[x] += item.second;
}
// 预处理前缀和
for (int i = 1; i <= alls.size(); i ++ ) s[i] = s[i - 1] + a[i];
// 处理询问
for (auto item : query)
{
int l = find(item.first), r = find(item.second);
cout << s[r] - s[l - 1] << endl;
}
return 0;
}
2.区间合并
题目描述:
给定 n 个区间 [li,ri],要求合并所有有交集的区间。注意如果在端点处相交,也算有交集。输出合并完成后的区间个数。例如:[1,3] 和 [2,6] 可以合并为一个区间 [1,6]。
测试样例:
输入:
5
1 2
2 4
5 6
7 8
7 9
输出:
3
代码如下:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int, int> P;//pair<int, int>是一种数据类型
const int N=100010;
int n;
vector<P> segs;
void merge(vector<P> &segs)//引用
{
vector<P> res;
sort(segs.begin(),segs.end());//pair默认优先按照第一个数排序
int st=-2e9,ed=-2e9;
for(auto seg: segs)
{
if(ed<seg.first)//交点也算有交集
{
if(st!=-2e9) res.push_back({st,ed});//需要先读入一组区间
st=seg.first,ed=seg.second;
}
else ed=max(ed,seg.second);//更新区间
}
if(st!=-2e9) res.push_back({st,ed});//特判区间不为空时,加上最后一组区间
segs=res;
}
int main()
{
cin>>n;
for(int i=0; i<n; i++)
{
int l,r;
cin>>l>>r;
segs.push_back({l,r});
}
merge(segs);
cout<<segs.size()<<endl;
return 0;
}