Gym - 101964E Fishermen(差分区间修改)

题目如上:c++

题意:题意:n条鱼,每条鱼有本身的坐标
有m个捕鱼人,每个捕鱼人都给出x坐标(y坐标默认为0)
每个捕鱼人都有一个范围 l ,在范围内都能捕鱼,距离为 |a-x|+b
spa

问最后每一个捕鱼人对应能够捕捉到多少条鱼code

思路:blog

其实咱们稍微思考如下就能够知道:看一下样例中给的图it


(1)咱们会发现 l 以上的全部鱼都不可能被捕到。 ( fish.y > l ) 就不能捕到class

(2)若是从捕鱼人的角度去看的话,咱们可能须要两重循环,(对人和鱼都遍历)循环

可是若是计算鱼的贡献的话,咱们能够经过计算找到图上 【L,R】 贡献范围,那么只须要对鱼遍历一次而后对区间内进行运算便可。遍历

因为题目中给出的人在x轴的位置是随机的,因此还要先记录一次id顺序,最后在映射一次输出结果。im

#include <bits/stdc++.h>
using namespace std;
typedef  long long ll;
const int maxn = 2e5+7;
struct fish
{
    int x,y;
}fishes[maxn];
struct fm
{
    int x,id;
    bool operator <(const fm &a)const 
    {
        return x<a.x;
    }
    
}fishmen[maxn];
int sum[maxn],ans[maxn];
int main(){
    int n,m,l;
    scanf("%d %d %d",&n,&m,&l);
    for (int i=1;i<=n;i++)
        scanf("%d %d",&fishes[i].x,&fishes[i].y);
    for (int i=1;i<=m;i++) {
        scanf("%d",&fishmen[i].x);
        fishmen[i].id=i;//输入的顺序 
    }
    sort(fishmen+1,fishmen+m+1);
    for (int i=1;i<=n;i++){
        if (fishes[i].y-l>0) continue;
        fm tmp;
        tmp.x=fishes[i].x-l+fishes[i].y;
        int L=lower_bound(fishmen+1,fishmen+m+1,tmp)-fishmen;
        tmp.x=fishes[i].x+l-fishes[i].y;
        int R=upper_bound(fishmen+1,fishmen+m+1,tmp)-fishmen;
        sum[L]++;
        sum[R]--;
    }
    for (int i=1;i<=m;i++){
        sum[i]+=sum[i-1];
        ans[fishmen[i].id]=sum[i];
    }
    for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}
相关文章
相关标签/搜索