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

题目如上:

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

问最后每个捕鱼人对应可以捕捉到多少条鱼

思路:

其实我们稍微思考以下就可以知道:看一下样例中给的图


(1)我们会发现 l 以上的所有鱼都不可能被捕到。 ( fish.y > l ) 就不能捕到

(2)如果从捕鱼人的角度去看的话,我们可能需要两重循环,(对人和鱼都遍历)

但是如果计算鱼的贡献的话,我们可以通过计算找到图上 【L,R】 贡献范围,那么只需要对鱼遍历一次然后对区间内进行运算即可。

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

#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;
}

原文地址:https://www.cnblogs.com/Tianwell/p/11778494.html

时间: 2024-10-05 05:49:59

Gym - 101964E Fishermen(差分区间修改)的相关文章

树状数组区间修改,区间更新:差分数组的运用

树状数组最原始的作用就是求前缀和,可以实现单点修改和区间查询. 但是假设现在有: 1.区间修改,单点查询 2.区间修改,区间查询 但是又不想敲线段树怎么办? 就用树状数组喽. 假设现在有一个原数组a(假设a[0] = 0),有一个数组d,d[i] = a[i] - a[i-1],那么 a[i] = d[1] + d[2] + .... + d[i] d数组就是差分数组 所以求a[i]就可以用树状数组维护d[i]的前缀和 区间修改,单点查询: 根据d的定义,对[l,r]区间加上x,那么a[l]和a

区间修改的离线查询——差分数组

差分数组这样的优化表示方法(在我们日常生活中)十分常见 如果我们假设有一列数a[1],a[2],a[3]... 那么若这样的差分数组表示为d[1],d[2],d[3]... 则有d[1]=a[1]; //一般我们也可以假设一个a[0]=0,就可以和下面的一样了 d[2]=a[2]-a[1]; d[3]=a[3]-a[2]; ... 差分数组应用很多,不过大部分都需要具体题目具体分析 但是在区间修改的离线查询中,差分数组是一个很优秀的线性算法 E.G. 题目描述链接 宾馆房间 hotelroom

【LuoguP3038/[USACO11DEC]牧草种植Grass Planting】树链剖分+树状数组【树状数组的区间修改与区间查询】

模拟题,可以用树链剖分+线段树维护. 但是学了一个厉害的..树状数组的区间修改与区间查询.. 分割线里面的是转载的: -------------------------------------------------------------------------------- [ 3 ]  上面都不是重点--重点是树状数组的区间修改+区间查询 这个很好玩 其实也挺简单 首先依旧是引入delta数组 delta[i]表示区间 [i, n] 的共同增量 于是修改区间 [l, r] 时修改 delt

树状数组 小白篇(2)暨区间修改

这篇主要来讲一讲树状数组的区间修改 因为一个一个点改,毫无疑问耗时太长 所以,机智的人类YY出了用差分来表示数组 为了便于理解,简单一点数组{an}:a[1]=0, a[2]=0, a[3]=0, a[4]=0, a[5]=0, a[6]=0 ,a[7]=0, a[8]=0, a[9]=0 用差分思想,delta[x]表示a[x]-a[x-1] 显然,一开始delta[]=0 我们先计算出前n项和{sn}来 然后别眨眼,下面就是见证奇迹的时刻! 有个分界线显得正式一点 我们要把a[3]到a[6]

非递归线段树区间修改区间求和的两种实现(以POJ 3468为例)

题意:就是一个数列,支持  查询区间和  以及  区间内的数都加上 C . 递归线段树很好写,就不讲了. 递归版本        : 内存:6500K   时间:2.6 秒 非递归版本一: 内存:4272K   时间:1.1秒 非递归版本二: 内存:4272K   时间:1.3秒 -------------------------------------------------------------------------------------------------------------

洛谷 P3368 【模板】树状数组 2 如题(区间修改+单点查询)

P3368 [模板]树状数组 2 时空限制1s / 128MB 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含2或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x 含义:输出

树状数组实现区间修改+区间查询

事实上,这只是我弱弱的luogu博客的存档-- 线段树模板(1) 题意要求:给定一个序列,支持区间修改和区间查询. 智障数据结构模板题-- 当然,题目名字告诉我们要用线段树.但是线段树很长,容易出现问题,而且跑得稍慢,所以就有dalao开始yy:可不可以让树状数组支持区间修改和查询呢? 于是伟大的"超级树状数组"横空出世了. 首先,我们看树状数组是如何支持区间修改的: 设 tree[i]=a[i]-a[i-1] (差分),那么容易得到: tree[1]+tree[2]+--+tree[

关于树状数组的区间修改和单点查询

写在前面 之前一直不知道树状数组可以支持区间修改,所以写一篇博客记录一下. 首先给个小栗子: 如下图: 利用差分的思路,就得到下图: 那么如果我们要求将2~4的所有元素+2呢?我们就可以得到下图: 可以发现,差分的第二项和第五项一个加了2,一个减了2,所以对于每次区间[l,r]操作,我们只需要在l和r+1的位置加.减操作值即可,证明也很简单,首先操作区间内的数的差肯定不会变,所以区间内的一段相同,因为第一项增加了一个值k,所以他与前面一项的差就增加了k,最后一项增加了k,最后一项的后一项与最后一

bzoj 3779 重组病毒 —— LCT+树状数组(区间修改+区间查询)

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3779 RELEASE操作可以对应LCT的 access,RECENTER则是 makeroot: 考虑颜色数,把一条实边变成虚边,子树+1,虚变实子树-1: 但有换根操作,怎么维护子树? 也可以用 dfs 序线段树维护,其实换 rt 只是 splay 的根方向改变,对应的子树还是可以找到的: 注意虚边变实或实边变虚时要找子树,不是直接找那个儿子,而是找那个儿子所在 splay 的根: 然后