大纲
离散化
思路:因为存储的下标实在太大了,如果直接开这么大的数组,根本不现实 有人可能会提出用哈希表,哈希表可以吗?答案也是不可以的,因为哈希表不能像离散化那样缩小数组的空间,导致我们可能需要从-e9遍历到1e9 本题使用离散化,离散化的本质,是映射,将间隔很大的点,映射到相邻的数组元素中。减少对空间的需求,也减少计算量。本文用于存储这个关系的数组是alls[N];特地说明下,为什么要开300000+10呢,因为提前考虑了前缀和的因素,加上了2*m个点,又因为怕出现数组越界,多加了10。什么时候会用完300000个空间呢,那就是无重复元素,外加n和m都是1e5次方。
#include<bits/stdc++.h>
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;
}
区间合并
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
int n;
vector<PII> nums,res;
int main(){
int st=-2e9,ed=-2e9;
cin>>n;
while(n--){
int l,r;
cin>>l>>r;
nums.push_back({l,r});
}
sort(nums.begin(),nums.end());
for(auto num:nums){
if(ed<num.first){
if(ed!=-2e9) res.push_back({st,ed});
st=num.first,ed=num.second;
}
else if(ed<num.second) ed = num.second;
}
res.push_back({st,ed});
cout<<res.size()<<endl;
return 0;
}