题意

有 \(n\) 个箱子,指定一个箱子开始向右推,如果碰到了别的箱子会令其移动,问 \(k\) 秒之后每个箱子所在的位置。

\(n\leq 10^5\).

分析

  • 转化成最短路模型,如果两个箱子 \(a,b\) 在 \(y\) 轴方向上投影有交,连边 \(a \rightarrow b\),边长为 \(x_{1b}-x_{2a}\).

  • 考虑优化建图,发现如果三个箱子 \(a,b,c\) 投影两两有交,\(a\) 和 \(c\) 之间不用连边。

  • 所以如果两个箱子 \(a,b\) 之间需要连边,当且仅当在从 \(a\) 到 \(b\) 的过程中不存在一个 \(x\) 满足 \(x\) 和 \(a,b\) 的投影都有交。

  • 考虑扫描线按 \(y\) 排序,因为此时加入的所有箱子的投影都是两两有交的,在加入一个箱子的时候和他左右相邻的两个箱子连边即可。容易证明如果两个箱子满足之前的条件,他们一定会连边。

  • 边数 \(O(n)\), 总时间复杂度为 \(O(nlogn)\)。

代码

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=2e5 + 7;
const LL inf=1e13;
int n,S,k,ndc,edc;
int vis[N],head[N];
LL dis[N],xl[N],xr[N],yl[N],yr[N];
struct data{
int opt,id;LL y;
bool operator <(const data &rhs)const{
if(xl[id]!=xl[rhs.id]) return xl[id]<xl[rhs.id];
return xr[id]<xr[rhs.id];
}
}q[N<<1];
set<data>s;
set<data>::iterator l,r;
struct edge{ int lst,to,c; }e[N<<2];
void Add(int a,int b,int c){
e[++edc]=(edge){head[a],b,c},head[a]=edc;
}
struct Heap{
int u;LL dis;
bool operator <(const Heap &b)const{
return b.dis<dis;
}
};
void dijk(){
priority_queue<Heap>Q;
fill(dis+1,dis+1+n,inf);dis[S]=0;
Q.push((Heap){S,dis[S]});
while(!Q.empty()){
int u=Q.top().u;Q.pop();
if(vis[u]) continue;vis[u]=1;
go(u)if(dis[u]+e[i].c<dis[v]){
dis[v]=dis[u]+e[i].c;
Q.push((Heap){v,dis[v]});
}
}
}
int main(){
n=gi(),S=gi(),k=gi();
rep(i,1,n){
xl[i]=gi(),yl[i]=gi(),xr[i]=gi(),yr[i]=gi();
q[++ndc]=(data){1,i,yl[i]};
q[++ndc]=(data){0,i,yr[i]+1};
}
sort(q+1,q+1+ndc,[&](const data &a,const data &b){return a.y<b.y||a.y==b.y&&a.opt<b.opt;});
rep(i,1,ndc){
if(q[i].opt){
s.insert( (data){0,q[i].id,0} );
r=s.lower_bound( (data){0,q[i].id,0} ),l=r++; if(l!=s.begin()) --l,Add(l->id,q[i].id,xl[q[i].id]-xr[l->id]);
if(r!=s.end()) Add(q[i].id,r->id,xl[r->id]-xr[q[i].id]);
}else s.erase( (data){0,q[i].id,0} );
}
dijk();
rep(i,1,n){
LL res;
if(dis[i]==inf||dis[i]>=k) res=0;
else res=k-dis[i];
printf("%lld%c",xl[i]+res,i==n?'\n':' ');
}
return 0;
}

牛客网NOIP赛前集训营-提高组(第八场)-B-推箱子[最短路优化建图]的更多相关文章

  1. 牛客网NOIP赛前集训营-普及组(第二场)和 牛客网NOIP赛前集训营-提高组(第二场)解题报告

    目录 牛客网NOIP赛前集训营-普及组(第二场) A 你好诶加币 B 最后一次 C 选择颜色 D 合法括号序列 牛客网NOIP赛前集训营-提高组(第二场) A 方差 B 分糖果 C 集合划分 牛客网N ...

  2. 牛客网NOIP赛前集训营-提高组(第二场)A 方差

    链接:https://www.nowcoder.com/acm/contest/173/A来源:牛客网 题目描述 一个长度为 m 的序列 b[1...m] ,我们定义它的方差为 ,其中  表示序列的平 ...

  3. [牛客网NOIP赛前集训营-提高组(第一场)]C.保护

    链接:https://www.nowcoder.com/acm/contest/172/C来源:牛客网 题目描述 C国有n个城市,城市间通过一个树形结构形成一个连通图.城市编号为1到n,其中1号城市为 ...

  4. 牛客网NOIP赛前集训营-提高组(第一场)

    牛客的这场比赛感觉真心不错!! 打得还是很过瘾的.水平也比较适合. T1:中位数: 题目描述 小N得到了一个非常神奇的序列A.这个序列长度为N,下标从1开始.A的一个子区间对应一个序列,可以由数对[l ...

  5. 比赛总结——牛客网 NOIP赛前集训营提高组模拟第一场

    第一场打的很惨淡啊 t1二分+前缀最小值没想出来,20分的暴力也挂了,只有10分 t2数位dp,调了半天,结果因为忘了判0的特殊情况WA了一个点,亏死 t3emmmm.. 不会 imone说是DSU ...

  6. 牛客网NOIP赛前集训营-提高组(第一场)B 数数字

    数数字 思路: 数位dp 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...

  7. 牛客网NOIP赛前集训营-提高组(第一场)A 中位数

    中位数 思路: 二分答案 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...

  8. 牛客网NOIP赛前集训营 提高组 第5场 T2 旅游

    [题解] 我们可以发现不在最小生成树上的边一定不能多次经过,因为一条不在最小生成树上的边(u,v)的边权比最小生成树上(u,v)之间的路径更长,选择不在最小生成树上的边一定不划算. 我们还需要确定最小 ...

  9. 牛客网NOIP赛前集训营-提高组(第四场)游记

    牛客网NOIP赛前集训营-提高组(第四场)游记 动态点分治 题目大意: \(T(t\le10000)\)组询问,求\([l,r]\)中\(k(l,r,k<2^{63})\)的非负整数次幂的数的个 ...

  10. 牛客网NOIP赛前集训营-提高组(第四场)B区间

    牛客网NOIP赛前集训营-提高组(第四场)B区间 题目描述 给出一个序列$ a_1  \dots   a_n$. 定义一个区间 \([l,r]\) 是好的,当且仅当这个区间中存在一个 \(i\),使得 ...

随机推荐

  1. python websocket client 使用

    import websocket ws = websocket.WebSocket() ws.connect("xx.xx.xx") ws.send("string&qu ...

  2. 2018-02-03-PY3下经典数据集iris的机器学习算法举例-零基础

    ---layout: posttitle: 2018-02-03-PY3下经典数据集iris的机器学习算法举例-零基础key: 20180203tags: 机器学习 ML IRIS python3mo ...

  3. Chained Declustering

          此论文描述了在无共享架构的多处理器机器上的数据库系统的数据冗余分布方法.该方法提高了系统的可用性,同时在单节点故障的情况下,可以很好的实现负载均衡.以下是论文的一些摘要,详细可以参见论文原 ...

  4. MariaDB数据表操作实例

    1. MariaDB 数据库操作实例 MariaDB>create database class; //创建class数据库 MariaDB>use class; MariaDB>c ...

  5. Keil下载时出现program fail错误的一个原因

    在使用Keil给STM32单片机编程的时候有时会出现Programing Failed!对于这样的错误网上有很多的教程,错误的原因也有很多,比如是单片机上锁,环境配置错误的原因导致.这里我将提供一种错 ...

  6. Python实例---模拟微信网页登录(day2)

    第三步: 实现长轮询访问服务器---day2代码 settings.py """ Django settings for weixin project. Generate ...

  7. TiDB数据库集群安装以及注意事项

    今天尝试安装tidb集群.详细的安装步骤我们参考:https://pingcap.com/docs-cn/op-guide/ansible-deployment/ . 不过安装之前需要一些注意事项. ...

  8. [BZOJ 4763]雪辉

    [BZOJ 4763] 雪辉 题意 给定一棵 \(n\) 个点的无根树, 点带权. \(q\) 次询问, 每次给定树上的若干路径, 求这些路径上的点共有多少种不同权值以及这些点的权值组成的集合的 \( ...

  9. sql语句查询月份的数据

    在实际项目中,经常需要按月查询数据,在这里把我用到的sql整理一下,以便日后查看. 例如,查询当月的数据 ),addtime,)),) 查询结果: 查询上月的数据,需要用另一个sql函数,datead ...

  10. Volley源码分析(三)NetWorkDispatcher分析

    NetWorkDispatcher分析 NetWorkDispatcher和CacheDispatcher一样,继承于Thread,在run方法中实现一个无限循环,代码如下 @Override pub ...