洛谷 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\)的倍数,接 ...
随机推荐
- 以太坊web3开发初步学习
以太坊web3开发初步学习 此文是对https://learnblockchain.cn/2018/04/15/web3-html/的学习再理解. 以太坊智能合约通过使用web3.js前端和智能合约交 ...
- 【UE4 设计模式】原型模式 Prototype Pattern
概述 描述 使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.如孙悟空猴毛分身.鸣人影之分身.剑光分化.无限剑制 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象, ...
- Java RMI学习与解读(一)
Java RMI学习与解读(一) 写在前面 本文记录在心情美丽的一个晚上. 嗯.就是心情很美丽. 那为什么晚上还要学习呢? emm... 卷... 卷起来. 全文基本都是根据su18师傅和其他师傅的文 ...
- UltraSoft - Beta - Scrum Meeting 2
Date: May 18th, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 建立Beta仓库管理增加服务器部署和Git协作文档 Liuzh 前端 查阅响应式布 ...
- UltraSoft - Beta - Scrum Meeting 3
20200519会议纪要 Date: May 19th, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 暂无 Liuzh 前端 暂无 Kkkk 前端 完成了前端 ...
- [对对子队]会议记录5.18(Scrum Meeting5)
今天已完成的工作 何瑞 工作内容:搭建第8关 相关issue:搭建关卡7.8.9 相关签入:feat:初步搭建了Lv8 吴昭邦 工作内容:搭建第8关 相关issue:搭建关卡7.8 ...
- 2021.9.12考试总结[NOIP模拟51]
T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...
- 2021.8.8考试总结[NOIP模拟33]
T1 Hunter 考场上一看期望直接状压拿了$45pts$跑了.结果正解只用$4$行? 把问题转化为一号猎人之前死的猎人数的期望加一. 期望的线性性. 对每个猎人$i$,$w_i+w_1$种情况中有 ...
- 洛谷 P5657 [CSP-S2019] 格雷码
链接: P5657 分析: 签到题,不过也有不少细节. 数据范围需要开 unsigned long long ,前年也有很多人因此丢了5分. pow 会出现神必错误,需要手写一个 mpow 函数. 算 ...
- 加法运算替代 牛客网 程序员面试金典 C++ Python
加法运算替代 牛客网 程序员面试金典 题目描述 请编写一个方法,实现整数的乘法.减法和除法运算(这里的除指整除).只允许使用加号. 给定两个正整数int a,int b,同时给定一个int type代 ...