2.1基础算法
1.双指针
2.位运算
3.离散化
1)去除重复元素
vector<int>all;
sort(all.begin() , all.end());//排序
all.erase(unique(all.begin() , all.end()) , all.end());//删除末尾的重复元素
2)代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 300010;
int a[N] , s[N];//a数组:在all数组数字所在位置+1 的地方存放他的值 ; s是a 的前缀和
int m,n;
vector<int>all;//存放所有的有改变的数组下标, 以及 l 和 r
vector<PII>add,query;
/**add存放的是{有改变的数组下标 , 增加的数字}
* query存放的是{需要访问的 l 和 r}
*/
//返回all数组中x的下标+1 , 即第几个数字
int find(int x){
int l = 0 , r = all.size()-1;
while(l<r){
int mid = l+r>>1;
if(all[mid]>=x) r = mid;
else l = mid+1;
}
return l+1;
}
int main()
{
scanf("%d%d", &n, &m);
while (n -- ){
int x,c;
scanf("%d%d", &x, &c);
all.push_back(x);
add.push_back({x,c});
}
while (m -- ){
int l , r;
scanf("%d%d", &l, &r);
query.push_back({l,r});
all.push_back(l);
all.push_back(r);
}
sort(all.begin() , all.end());
all.erase(unique(all.begin() , all.end()) , all.end());
for(auto p:add){
int x = find(p.first);
a[x]+=p.second;
}
for(int i = 1 ; i <= all.size() ; i++) s[i] = s[i-1]+a[i];
for(auto q:query){
int l = find(q.first) , r = find(q.second);
cout<<s[r]-s[l-1]<<endl;
}
return 0;
}
3.区间合并
1)按照区间左端点排序
2)代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int st = -1e9 , ed = -1e9;
typedef pair<int, int> PII;
vector<PII>seg;
void merge(vector<PII>&seg){
vector<PII> res;
sort(seg.begin() , seg.end());
for(auto p:seg){
if(p.first>ed){
if(st!=-1e9) res.push_back({st,ed});
st = p.first;
ed = p.second;
}
else ed = max(ed,p.second);
}
if(st!=-1e9) res.push_back({st,ed});
seg=res;
}
int main()
{
int n;
scanf("%d", &n);
while (n -- ){
int l,r;
scanf("%d%d", &l, &r);
seg.push_back({l,r});
}
merge(seg);
cout<<seg.size()<<endl;
return 0;
}