题目链接

题意:有一个数轴,上面有 \(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. Windows10使用技巧

    Windows10配置技巧 新机配置 "我的电脑"图标设置 在桌面右击鼠标=>个性化=>点击左侧"主题"=>点击相关的设置中的"桌面 ...

  2. [软工顶级理解组] Beta阶段项目展示

    目录 团队成员 软件介绍 项目简介 预期典型用户 功能描述 预期目标用户数 用户反馈 团队管理 分工协作 项目管理 取舍平衡 代码管理 程序测试 代码规范 文档撰写 继续开发指导性 用户沟通 需求分析 ...

  3. A*,IDA*—高档次的暴搜

    A*通过评价函数来判断当前状态是否可以到达最终状态(即可行性剪枝),来减少不必要的搜索. 例题--P2324 [SCOI2005]骑士精神 我们通过当前不在指定位置上的棋子个数为评价函数,\(used ...

  4. Java并发:Condition接口

    Condition 接口与 Lock 配合实现了等待 / 通知模式,这个和 Object 的监视器方法(wait.notify.notifyAll 等方法)一样,都是实现了等待 / 通知模式,但这两者 ...

  5. Go并发编程--Mutex/RWMutex

    目录 一.前言 二. Mutex 2.1 案例 三. 实现原理 3.1 锁的实现模式 3.2 Go Mutex 实现原理 3.2.1 加锁 3.2.2 解锁 四. 源码分析 4.1 Mutex基本结构 ...

  6. (转)linux下execl和system函数

    linux下,system函数和execl函数都是用于执行一条系统命令.今天仔细看了system函数的实现,想找出和execl函数的差别. 这里先进行一些背景知识补充: fork(创建一个新的进程): ...

  7. best-time-to-buy-and-sell-stock leetcode C++

    Say you have an array for which the i th element is the price of a given stock on day i. If you were ...

  8. pycharm的基本使用 、 Python的注释语法,变量,常量,垃圾回收机制,数据类型

    1.文件路径要注意 我把文件放在了D盘,如下图:你们可以根据自身情况设置 2.python环境要选择本地下载好的 如下图: 点击本机存在的环境,如果提示NO interpr,就点击第二步 如果还是没有 ...

  9. (1)Zookeeper在linux环境中搭建集群

    1.简介 ZooKeeper是Apache软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务.同步服务和命名注册.ZooKeeper的架构通过冗余服务实现高可用性.Zookeeper ...

  10. nginx + tomcat 实现负载均衡

    1.环境准备 服务器A上安装 nginx 作为代理服务器 服务器B上安装 tomcat,~/webapps 下创建 /test目录,创建 /index.html 内容为T1(生产环境中一般是一样的wa ...