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;
}
相關文章
相關標籤/搜索