### 题目链接 ###
题目大意:给定男生与女生的移动区间,问每个男生最大能遇上多少位女生。
分析:
1、每个男生的区间内,与多少个女生的区间重合,即为题目所求的能遇见的最大女生人数。
2、对于某个男生,假定他的区间为 ([) (L) (,) (R) (]),而第 (i) 位的女生区间为 ([) (l)(i) (,) (r)(i) (]) 。
显然,对于某个男生而言,女生们的区间可以分为这五类,而对答案做贡献的是第 2 、3 、4 号区间。
观察一下可以发现,这些有贡献的区间会满足,(l) (≤) (R) 。
而第一号区间也满足 (l) (≤) (R) 却不做贡献,是因为它的 (r) (<) (L) 。
3、故我们要求某一个男生的贡献,只需要统计有多少位女生的 (l) 既 (≤) 男生的 (R) 而又满足女生的 (r) (≥) 男生的 (L) ,即查询比 (l) (≤) (R) 的女生区间个数 减去 那些 (r) (<) (L) 的女生区间个数(注意没有等号)。
二分做法:
记录两个数组 (a[])、(b[]),分别表示女生区间以 (l) 从小到大排序 和 女生区间以 (r) 从小到大排序。
对于某个男生的区间([) (L) (,) (R) (]) ,在 (a[]) 中找到最后一个小于等于 (R) 的位置 (pos) ,则第 (1) ~ (pos) 号区间都满足 (l) (≤) (R) 。
在 (b[]) 中找到最后一个小于等于 (L)的位置 (或第一个大于 (L) 的位置 ),位置对减即可。
代码如下:
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
const int maxn = 200008;
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const ll INF = 1e18 + 10;
const double eps = 1e-6;
using namespace std;
int n,m;
ll ans;
struct People{
int l,r;
}a[maxn],b[maxn],c[maxn];
bool cmp1(People q,People w){
return q.r<w.r;
}
bool cmp2(People q,People w){
return q.l<w.l;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].l,&a[i].r);
for(int i=1;i<=m;i++) scanf("%d%d",&b[i].l,&b[i].r),c[i].l=b[i].l,c[i].r=b[i].r;
sort(b+1,b+m+1,cmp1);
sort(c+1,c+m+1,cmp2);
for(int i=1;i<=n;i++){
int st=lower_bound(b+1,b+m+1,People{0,a[i].l},cmp1)-b;
int en=upper_bound(c+1,c+m+1,People{a[i].r,0},cmp2)-c-1;
if(i!=n)printf("%d
",en-st+1);
else printf("%d", en-st+1);
}
return 0;
}
树状数组同理,需要离散化:
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
const int maxn = 200008;
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const ll INF = 1e18 + 10;
const double eps = 1e-6;
using namespace std;
int n,m;
int c[maxn<<2][2],f[maxn<<2];
struct People{
int l,r;
}a[maxn],b[maxn];
inline int lowbit(int x){return x&(-x);}
void update(int i,int x){
while(i<=800000){
c[i][x]++;
i+=lowbit(i);
}
return;
}
int query(int i,int x){
int ans=0;
while(i){
ans+=c[i][x];
i-=lowbit(i);
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
int cnt=0;
for(int i=1;i<=n;i++) {
scanf("%d%d",&a[i].l,&a[i].r);
f[++cnt]=a[i].l,f[++cnt]=a[i].r;
}
for(int i=1;i<=m;i++){
scanf("%d%d",&b[i].l,&b[i].r);
f[++cnt]=b[i].l,f[++cnt]=b[i].r;
}
sort(f+1,f+cnt+1);
int len=unique(f+1,f+cnt+1)-f-1;
int st,en;
for(int i=1;i<=m;i++){
st=lower_bound(f+1,f+len+1,b[i].l)-f;
en=lower_bound(f+1,f+len+1,b[i].r)-f;
update(st,0),update(en,1);
}
for(int i=1;i<=n;i++){
st=lower_bound(f+1,f+len+1,a[i].l)-f;
en=lower_bound(f+1,f+len+1,a[i].r)-f;
printf("%d
",query(en,0)-query(st-1,1));
}
return 0;
}