题目链接

题意:有一个数轴,上面有 \(n\) 个传送门,使用第 \(i\) 个传送门,你可以从 \(x_i\) 走到 \(y_i\),花费的时间为 \(t_i\) 秒。你的速度为 \(1\) 格/秒,有 \(m\) 次询问,每次你要从 \(a_i\) 走到 \(b_i\),最多使用一次传送门,问最少需要多少秒。

\(1 \leq n,m \leq 10^5\),\(0 \leq a_i,b_i \leq 10^9\)

我果然是要退役了,用未去重的数组离散化(

很显然对于第 \(j\) 个询问使用第 \(i\) 个传送门的情况,需要 \(|x_i-a_j|+|y_i-b_j|+t_i\) 秒的时间。

看那个绝对值有点像曼哈顿距离……这就启发我们将题目转换为:平面上有 \(n\) 个点,第 \(i\) 个点位于 \((x_i,y_i)\),有点权 \(t_i\)。有 \(m\) 次询问,要求与 \((a_i,b_i)\) 的曼哈顿距离加上点的权值最小的点。

为什么要这么转化呢?看到平面,我们就想到二维数点。将这 \(n+m\) 个点按 \(x\) 坐标排序,暴力将绝对值拆开,分四种情况更新答案就可以了。

注意事项:对每个询问,记得赋初值 \(|b_i-a_i|\)

//Coded by tzc_wk
/*
数据不清空,爆零两行泪。
多测不读完,爆零两行泪。
边界不特判,爆零两行泪。
贪心不证明,爆零两行泪。
D P 顺序错,爆零两行泪。
大小少等号,爆零两行泪。
变量不统一,爆零两行泪。
越界不判断,爆零两行泪。
调试不注释,爆零两行泪。
溢出不 l l,爆零两行泪。
*/
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a) a.begin(),a.end()
#define giveup(...) return printf(__VA_ARGS__),0;
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define mask(a) (1ll<<(a))
#define maskx(a,x) ((a)<<(x))
#define _bit(a,x) (((a)>>(x))&1)
#define _sz(a) ((int)(a).size())
#define filei(a) freopen(a,"r",stdin);
#define fileo(a) freopen(a,"w",stdout);
#define fileio(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#define put(x) putchar(x)
#define eoln put('\n')
#define space put(' ')
#define y1 y_chenxiaoyan_1
#define y0 y_chenxiaoyan_0
#define int long long
typedef pair<int,int> pii;
inline int read(){
int x=0,neg=1;char c=getchar();
while(!isdigit(c)){
if(c=='-') neg=-1;
c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*neg;
}
inline void print(int x){
if(x<0){
putchar('-');
print(abs(x));
return;
}
if(x<=9) putchar(x+'0');
else{
print(x/10);
putchar(x%10+'0');
}
}
inline int qpow(int x,int e,int _MOD){
int ans=1;
while(e){
if(e&1) ans=ans*x%_MOD;
x=x*x%_MOD;
e>>=1;
}
return ans;
}
int _abs(int x){
return (x<0)?-x:x;
}
int n,m;
struct ycxakioi{
int x,y,t;
friend bool operator <(ycxakioi ycx,ycxakioi tzc){
return ycx.x<tzc.x;
}
} p[200005];
struct query{
int x,y,id,ans;
friend bool operator <(query x,query y){
return x.x<y.x;
}
} q[200005];
int keyx[200005],xc,yc,keyy[200005],hsx[200005],cx,hsy[200005],cy;
struct SegTree{
struct node{
int l,r,mn;
} s[200005<<2];
inline void init(){
fz(i,0,(200005<<2)-1) s[i].mn=0x3f3f3f3f3f3f3f3fll;
}
inline void build(int k,int l,int r){
s[k].l=l;s[k].r=r;
if(l==r) return;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
inline void modify(int k,int ind,int x){
if(s[k].l==s[k].r){
s[k].mn=min(s[k].mn,x);
return;
}
int mid=(s[k].l+s[k].r)>>1;
if(ind<=mid) modify(k<<1,ind,x);
else modify(k<<1|1,ind,x);
s[k].mn=min(s[k<<1].mn,s[k<<1|1].mn);
}
inline int query(int k,int l,int r){
if(l<=s[k].l&&s[k].r<=r){
return s[k].mn;
}
int mid=(s[k].l+s[k].r)>>1;
if(r<=mid) return query(k<<1,l,r);
else if(l>mid) return query(k<<1|1,l,r);
else return min(query(k<<1,l,mid),query(k<<1|1,mid+1,r));
}
} s1,s2,s3,s4;
int anss[200005];
signed main(){
// filei("P4088_5.in");
n=read(),m=read();
fz(i,1,n){
p[i].x=read();
p[i].y=read();
p[i].t=read();
keyx[++xc]=p[i].x;
keyy[++yc]=p[i].y;
}
fz(i,1,m){
q[i].x=read();
q[i].y=read();
q[i].id=i;
q[i].ans=_abs(q[i].y-q[i].x);
keyx[++xc]=q[i].x;
keyy[++yc]=q[i].y;
}
sort(keyx+1,keyx+xc+1);sort(keyy+1,keyy+yc+1);
keyx[0]=0x3f3f3f3f;keyy[0]=0x3f3f3f3f;
fz(i,1,xc) if(keyx[i]!=keyx[i-1]) hsx[++cx]=keyx[i];
fz(i,1,yc) if(keyy[i]!=keyy[i-1]) hsy[++cy]=keyy[i];
fz(i,1,n) p[i].x=lower_bound(hsx+1,hsx+cx+1,p[i].x)-hsx;
fz(i,1,n) p[i].y=lower_bound(hsy+1,hsy+cy+1,p[i].y)-hsy;
fz(i,1,m) q[i].x=lower_bound(hsx+1,hsx+cx+1,q[i].x)-hsx;
fz(i,1,m) q[i].y=lower_bound(hsy+1,hsy+cy+1,q[i].y)-hsy;
// fz(i,1,n) cout<<p[i].x<<" "<<p[i].y<<" "<<p[i].t<<endl;
// fz(i,1,m) cout<<q[i].x<<" "<<q[i].y<<endl;
sort(p+1,p+n+1);
sort(q+1,q+m+1);
s1.build(1,1,cy);s2.build(1,1,cy);s3.build(1,1,cy);s4.build(1,1,cy);
s1.init();s2.init();s3.init();s4.init();
p[n+1].x=0x3f3f3f3f;
int cur=1;
fz(i,1,m){
// if(i>=5000) cerr<<i<<endl;
while(p[cur].x<=q[i].x){
s1.modify(1,p[cur].y,-hsy[p[cur].y]-hsx[p[cur].x]+p[cur].t);
s2.modify(1,p[cur].y,hsy[p[cur].y]-hsx[p[cur].x]+p[cur].t);
cur++;
}
q[i].ans=min(q[i].ans,s1.query(1,1,q[i].y)+hsx[q[i].x]+hsy[q[i].y]);
q[i].ans=min(q[i].ans,s2.query(1,q[i].y,cy)+hsx[q[i].x]-hsy[q[i].y]);
}
cur=n;
fd(i,m,1){
// cerr<<i<<endl;
while(p[cur].x>=q[i].x&&cur>=1){
s3.modify(1,p[cur].y,hsy[p[cur].y]+hsx[p[cur].x]+p[cur].t);
s4.modify(1,p[cur].y,-hsy[p[cur].y]+hsx[p[cur].x]+p[cur].t);
cur--;
}
q[i].ans=min(q[i].ans,s4.query(1,1,q[i].y)-hsx[q[i].x]+hsy[q[i].y]);
q[i].ans=min(q[i].ans,s3.query(1,q[i].y,cy)-hsx[q[i].x]-hsy[q[i].y]);
}
fz(i,1,m) anss[q[i].id]=q[i].ans;
fz(i,1,m) cout<<anss[i]<<endl;
return 0;
}

洛谷 P4088 [USACO18FEB] Slingshot P(线段树+二维数点)的更多相关文章

  1. 洛谷P4088 [USACO18FEB]Slingshot

    题面 大意:给出n个弹弓,可以用ti的时间把xi位置运到yi,在给出m组询问,求xj到yj最小时间. sol:首先如果不用弹弓,时间应为abs(xj-yj).否则时间就是abs(xi-xj)+abs( ...

  2. 洛谷 P3373 【模板】线段树 2

    洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...

  3. 洛谷P3899 [湖南集训]谈笑风生(线段树合并)

    题意 题目链接 Sol 线段树合并板子题,目前我看到两种写法,分别是这样的. 前一种每次需要新建一个节点,空间是\(O(4nlogn)\) 后者不需要新建,空间是\(O(nlogn)\)(面向数据算空 ...

  4. loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分

    $ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...

  5. 洛谷P3372 【模板】线段树 1

    P3372 [模板]线段树 1 153通过 525提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 [模板]线段树1(AAAAAAAAA- [模板]线段树1 洛谷 ...

  6. 洛谷P4891 序列(势能线段树)

    洛谷题目传送门 闲话 考场上一眼看出这是个毒瘤线段树准备杠题,发现实在太难调了,被各路神犇虐哭qwq 考后看到各种优雅的暴力AC......宝宝心里苦qwq 思路分析 题面里面是一堆乱七八糟的限制和性 ...

  7. 洛谷 P2574 XOR的艺术(线段树 区间异或 区间求和)

    To 洛谷.2574 XOR的艺术 题目描述 AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏.在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下 1. 拥有一个伤害串为长度为n的 ...

  8. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

  9. Bzoj5294/洛谷P4428 [Bjoi2018]二进制(线段树)

    题面 Bzoj 洛谷 题解 考虑一个什么样的区间满足重组之后可以变成\(3\)的倍数.不妨设\(tot\)为一个区间内\(1\)的个数.如果\(tot\)是个偶数,则这个区间一定是\(3\)的倍数,接 ...

随机推荐

  1. vue.$set实现原理

    上源码: export function set (target: Array<any> | Object, key: any, val: any): any { if (process. ...

  2. [对对子队]会议记录4.16(Scrum Meeting7)

    今天已完成的工作 何瑞 ​ 工作内容:完成成本和分数系统 ​ 相关issue:实现成本和分数系统的逻辑 ​ 相关签入:4.16签入1 吴昭邦 ​ 工作内容:对接流水线和成本和分数系统 ​ 相关issu ...

  3. Noip模拟14 2021.7.13

    T1 队长快跑 本身dp就不强的小马看到这题并未反映过来是个dp(可能是跟题面太过于像那个黑题的队长快跑相似) 总之,基础dp也没搞出来,不过这题倒是启发了小马以后考试要往dp哪里想想 $dp_{i, ...

  4. (转载)linux chmod命令用法

    chmod----改变一个或多个文件的存取模式(mode) chmod [options] mode files   只能文件属主或特权用户才能使用该功能来改变文件存取模式.mode可以是数字形式(八 ...

  5. Python3 TypeError: initial_value must be str or None, not bytes

    response.read() returns an instance of bytes while StringIO is an in-memory stream for text only. Us ...

  6. Spring Cloud Alibaba 使用 feign 和 rebion 进行服务消费

    微服务的服务消费,一般是使用 feign 和 rebion 调用服务提供,进行服务的消费,本文将实战使用代码讲解服务的消费. 微服务环境的搭建 创建一个 springboot 项目,springboo ...

  7. 倒谱Cepstrum本质的理解

    1.理解: 信号叠加时,不是都是线性关系(时域相互+ 频率相加):有的时候是两种信号成分相乘得到的,(时域卷积,频域相乘):比如很多齿轮啮合时振动信号调制现象,电机的轴向与径向的振动耦合时采集到的振动 ...

  8. 使用gitlab runner 进行CI(四):使用Gitlab Page托管项目文档

    目录 1.什么是Gitlab Pages 2.开启Gitlab Pages 3.基本过程 4.托管markdown文档 4.1 安装sphinx等依赖 4.2 配置项目的sphinx配置 4.3 编写 ...

  9. 攻防世界 WEB 高手进阶区 NSCTF web2 Writeup

    攻防世界 WEB 高手进阶区 NSCTF web2 Writeup 题目介绍 题目考点 php基本函数语法 加密解密函数 base64_decode().str_rot13() 字符串反转函数 str ...

  10. EF Core 小技巧:迁移已经应用到数据库,如何进行迁移回退操作?

    场景描述:项目中存在两个迁移 Teacher 和 TeachingPlan ,TeachingPlan 在 Teacher 之后创建,并且已经执行 dotnet ef database update ...