洛谷 P4088 [USACO18FEB] Slingshot P(线段树+二维数点)
题意:有一个数轴,上面有 \(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(线段树+二维数点)的更多相关文章
- 洛谷P4088 [USACO18FEB]Slingshot
题面 大意:给出n个弹弓,可以用ti的时间把xi位置运到yi,在给出m组询问,求xj到yj最小时间. sol:首先如果不用弹弓,时间应为abs(xj-yj).否则时间就是abs(xi-xj)+abs( ...
- 洛谷 P3373 【模板】线段树 2
洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...
- 洛谷P3899 [湖南集训]谈笑风生(线段树合并)
题意 题目链接 Sol 线段树合并板子题,目前我看到两种写法,分别是这样的. 前一种每次需要新建一个节点,空间是\(O(4nlogn)\) 后者不需要新建,空间是\(O(nlogn)\)(面向数据算空 ...
- loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分
$ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...
- 洛谷P3372 【模板】线段树 1
P3372 [模板]线段树 1 153通过 525提交 题目提供者HansBug 标签 难度普及+/提高 提交 讨论 题解 最新讨论 [模板]线段树1(AAAAAAAAA- [模板]线段树1 洛谷 ...
- 洛谷P4891 序列(势能线段树)
洛谷题目传送门 闲话 考场上一眼看出这是个毒瘤线段树准备杠题,发现实在太难调了,被各路神犇虐哭qwq 考后看到各种优雅的暴力AC......宝宝心里苦qwq 思路分析 题面里面是一堆乱七八糟的限制和性 ...
- 洛谷 P2574 XOR的艺术(线段树 区间异或 区间求和)
To 洛谷.2574 XOR的艺术 题目描述 AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏.在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下 1. 拥有一个伤害串为长度为n的 ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- Bzoj5294/洛谷P4428 [Bjoi2018]二进制(线段树)
题面 Bzoj 洛谷 题解 考虑一个什么样的区间满足重组之后可以变成\(3\)的倍数.不妨设\(tot\)为一个区间内\(1\)的个数.如果\(tot\)是个偶数,则这个区间一定是\(3\)的倍数,接 ...
随机推荐
- 时间轮机制在Redisson分布式锁中的实际应用以及时间轮源码分析
本篇文章主要基于Redisson中实现的分布式锁机制继续进行展开,分析Redisson中的时间轮机制. 在前面分析的Redisson的分布式锁实现中,有一个Watch Dog机制来对锁键进行续约,代码 ...
- 封装一个的toast弹出框(vue项目)
逆风的方向,更适合飞翔 实现效果 实现步骤 先写出一个toast组件 // Toast.vue <template> <div id="toast" :class ...
- [no code][scrum meeting] Alpha 4
项目 内容 会议时间 2020-04-09 会议主题 OCR相关的技术展示与讨论 会议时长 30min 参会人员 全体成员 $( "#cnblogs_post_body" ).ca ...
- [Beta]the Agiles Scrum Meeting 6
会议时间:2020.5.20 21:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 issue yjy 帮助成员解决配置环境问题 tq 增加功能:添加多个评测机 评测部分增加更多评测指标 ...
- rabbitmq死信队列和延时队列的使用
死信队列&死信交换器:DLX 全称(Dead-Letter-Exchange),称之为死信交换器,当消息变成一个死信之后,如果这个消息所在的队列存在x-dead-letter-exchange ...
- FastAPI 学习之路(五十五)操作Redis
之前我们分享了操作关系型数据库,具体文章, FastAPI 学习之路(三十二)创建数据库 FastAPI 学习之路(三十三)操作数据库 FastAPI 学习之路(三十四)数据库多表操作 这次我们分享的 ...
- Python 类似 SyntaxError: Non-ASCII character '\xc3' in file
Python 类似 SyntaxError: Non-ASCII character '\xc3' in file 产生这个问题的原因: python 的默认编码文件是ACSII,而编辑器将文件保存为 ...
- AtCoder Beginner Contest 210题解
A B 过水,略... C 统计长度为k的区间的最多本质不同的数.用尺取法维护下左右指针就可以了.调了许久的原因是更新答案时出现了问题. 当我移动指针时,我们应该移动一个就更新一个,而不是将移动与更新 ...
- 应对gitee容量超限. 保留star/fork/评论
应对gitee容量超限 进入企业版,"管理"-"仓库管理",点"清空仓库". 在E:\gitee目录上右击,"git bash h ...
- 【mysql1】如何删除MySQL内存|不再跟新系列
完全卸载mysql的具体步骤: 包括停止服务 + 卸载相关程序 + 删除注册表等等 步骤一: windows键+R-->Control-->程序和功能:所有MySQL程序点击右键 ...