抓娃娃
前缀和+lower_bound+upper_bound
思路:其实就是求区间是否经过线段的中点,因为
这个条件,说明只要区间经过线段中点就肯定能包含它。但有的中点是小数不好处理,于是乘以2
lower_bound+upper_bound:
// 升序数组中:
upper_bound(a.begin(), a.end(), x); // 查找第一个 > x的元素
lower_bound(a.begin(), a.end(), x); // 查找第一个 >= x的元素
// 降序数组中:
upper_bound(a.begin(), a.end(), x, greater<type>()); // 查找第一个 < x的元素
lower_bound(a.begin(), a.end(), x, greater<type>()); // 查找第一个 <= x的元素
- lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
- upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
在从大到小的排序数组中,重载lower_bound()和upper_bound()
- lower_bound( begin,end,num,greater()
):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 - upper_bound( begin,end,num,greater() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
注意要减去首地址,否则会报错。且使用之前,要相应对数组排序
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
vector<ll> v;
int main()
{
ll n,m;
cin>>n>>m;
for(ll i=0;i<n;i++)
{
ll l,r;
cin>>l>>r;
v.push_back(l+r);
}
sort(v.begin(),v.end());
for(ll i=0;i<m;i++)
{
ll l,r;
cin>>l>>r;
l*=2;
r*=2;
ll L=lower_bound(v.begin(),v.end(),l)-v.begin();
ll R=upper_bound(v.begin(),v.end(),r)-v.begin();
cout<<R-L<<endl;
}
return 0;
}