4070: [Apio2015]雅加达的摩天楼

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 464  Solved: 164
[Submit][Status][Discuss]

Description

印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1。除了这 N 座摩天楼外,雅加达市没有其他摩天楼。

 
有 M 只叫做 “doge” 的神秘生物在雅加达市居住,它们的编号依次是 0 到 M−1。编号为 i 的 doge 最初居住于编号为 Bi 的摩天楼。每只 doge 都有一种神秘的力量,使它们能够在摩天楼之间跳跃,编号为 i 的 doge 的跳跃能力为 Pi (Pi>0)。
 
在一次跳跃中,位于摩天楼 b 而跳跃能力为 p 的 doge 可以跳跃到编号为 b−p (如果 0≤b−p<N)或 b+p (如果 0≤b+p<N)的摩天楼。
 
编号为 0 的 doge 是所有 doge 的首领,它有一条紧急的消息要尽快传送给编 号为 1 的 doge。任何一个收到消息的 doge 有以下两个选择:
 
跳跃到其他摩天楼上;
将消息传递给它当前所在的摩天楼上的其他 doge。
请帮助 doge 们计算将消息从 0 号 doge 传递到 1 号 doge 所需要的最少总跳跃步数,或者告诉它们消息永远不可能传递到 1 号 doge。
 

Input

输入的第一行包含两个整数 N 和 M。

 
接下来 M 行,每行包含两个整数 Bi 和 Pi。
 

Output

输出一行,表示所需要的最少步数。如果消息永远无法传递到 1 号 doge,输出 −1。

 

Sample Input

5 3
0 2
1 1
4 1

Sample Output

5
explanation
下面是一种步数为 5 的解决方案:
0 号 doge 跳跃到 2 号摩天楼,再跳跃到 4 号摩天楼(2 步)。
0 号 doge 将消息传递给 2 号 doge。
2 号 doge 跳跃到 3 号摩天楼,接着跳跃到 2 号摩天楼,再跳跃到 1 号摩天楼(3 步)。
2 号 doge 将消息传递给 1 号 doge。

HINT

子任务

所有数据都保证 0≤Bi<N。
 
子任务 1 (10 分)
1≤N≤10
1≤Pi≤10
2≤M≤3
子任务 2 (12 分)
1≤N≤100
1≤Pi≤100
2≤M≤2000
子任务 3 (14 分)
1≤N≤2000
1≤Pi≤2000
2≤M≤2000
子任务 4 (21 分)
1≤N≤2000
1≤Pi≤2000
2≤M≤30000
子任务 5 (43 分)
1≤N≤30000
1≤Pi≤30000
2≤M≤30000

Source

想法:因为同一个doge不会再跑回来,所以这样暴力连边:Bi->Bi+k*Pi dis=k;K∈N.O(n^2)

另一个暴力:每种P,对于每种模数[0,P-1]。建一条轨道,轨道之间连双向边边权为1.然后Bi直接连Bi对应的轨道点P,边权为0.O(n^2)

优化第二个暴力:如果这个模数上并没有点那就不用建了。

分析一发复杂度:最坏情况,那肯定是所有轨道上都只有一个点。模数越大,一个点要建的轨道越小:N/P。所以最坏数据P从1开始,每个模数都有一个。

M=1+2+3+...+X。X=sqrt (2*M) 所以共O(sqrt(2*M)*n)条边...理论复杂度过了,但也许需要卡卡空间.....

#include<cstdio>
#include<vector>
#include<algorithm> #define usint unsigned short int
#define next(x) x==M?1:x+1
#define swap(a,b) a^=b,b^=a,a^=b;
//1<<16 -1
const int len(),N(),INF(0x7fffffff),M();
int n,m,now,S,T,last[len+];
struct Data{usint B,P,k;}doge[len+];
bool cmp(Data X,Data Y){if(X.P==Y.P)return X.k<Y.k;return X.P<Y.P;}
struct Node{int nd,nx;}bot[len+];
int tot,first[len+],Down[N+],Up[N+];//卡空间
usint To[N+];
void add(int a,int b){bot[++tot]=(Node){b,first[a]};first[a]=tot;}
template <class T>void read(T &x)
{
x=; char ch=getchar(); int f=;
while(ch<''||ch>''){f=(ch=='-');ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
x=f?-x:x;
}
int q[M+],l,h,x,y; int dis[N+]; bool flag[N+];
void Spfa()
{
for(int i=;i<=now;i++)dis[i]=INF;//dis[0]=0;
q[l=]=S; dis[S]=; h=; flag[S]=;
while(h!=l)
{
h=next(h); x=q[h]; y=next(h);
if(x<=n)
{
for(int v=first[x];v;v=bot[v].nx)
if(dis[bot[v].nd]>dis[x])
{
dis[bot[v].nd]=dis[x];
if(!flag[bot[v].nd])
{
l=next(l);
q[l]=bot[v].nd; flag[bot[v].nd]=;
if(dis[q[l]]>dis[q[y]])swap(q[y],q[l]);
}
}
}else
{
if(dis[To[x]]>dis[x])
{
dis[To[x]]=dis[x];
if(!flag[To[x]])
{
l=next(l);
q[l]=To[x]; flag[To[x]]=;
if(dis[q[l]]>dis[q[y]])swap(q[y],q[l]);
}
}
if(dis[Down[x]]>dis[x]+)
{
dis[Down[x]]=dis[x]+;
if(!flag[Down[x]])
{
l=next(l);
q[l]=Down[x]; flag[Down[x]]=;
if(dis[q[l]]>dis[q[y]])swap(q[y],q[l]);
}
}
if(dis[Up[x]]>dis[x]+)
{
dis[Up[x]]=dis[x]+;
if(!flag[Up[x]])
{
l=next(l);
q[l]=Up[x]; flag[Up[x]]=;
if(dis[q[l]]>dis[q[y]])swap(q[y],q[l]);
}
}
}
flag[x]=;
}
}
int main()
{
read(n),read(m);
for(int i=;i<=m;i++)
{
read(doge[i].B),read(doge[i].P);
doge[i].k=doge[i].B%doge[i].P;
}
S=doge[].B;T=doge[].B;
std::sort(doge+,doge++m,cmp);
now=n;
for(int i=;i<=m;i++)
{
if(doge[i].P!=doge[i-].P || doge[i].k!=doge[i-].k)
for(int j=doge[i].k;j<n;j+=doge[i].P)
{
To[++now]=j;
if(j!=doge[i].k)Down[now]=now-;else Down[now]=now;
if(j+doge[i].P<n)Up[now]=now+;else Up[now]=now;
last[j]=now;
}
add(doge[i].B,last[doge[i].B]);
}
Spfa();
printf("%d",dis[T]!=INF?dis[T]:-);
return ;
}

BZOJ 4070:[APIO2015]雅加达的摩天楼 最短路的更多相关文章

  1. bzoj 4070 [Apio2015]雅加达的摩天楼 Dijkstra+建图

    [Apio2015]雅加达的摩天楼 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 644  Solved: 238[Submit][Status][D ...

  2. bzoj 4070: [Apio2015]雅加达的摩天楼【spfa】

    明明是个最短路却有网络流一样的神建图= A = 首先要是暴力建图的话最坏有O(nm)条边.所以优化建图. 考虑分块思想,设bs=sqrt(n),对于p大于bs的,直接连边即可,最多有sqrt(n)条, ...

  3. BZOJ 4070 [Apio2015]雅加达的摩天楼 ——分块 SPFA

    挺有趣的分块的题目. 直接暴力建边SPFA貌似是$O(nm)$的. 然后考虑分块,$\sqrt n$一下用虚拟节点辅助连边, 以上的直接暴力连边即可. 然后卡卡时间,卡卡空间. 终于在UOJ上T掉辣. ...

  4. BZOJ 4070: [Apio2015]雅加达的摩天楼 根号分治+spfa

    此题卡Dijkstra... Code: #include <bits/stdc++.h> #define N 30005 #define M 4000000 #define ll lon ...

  5. 4070: [Apio2015]雅加达的摩天楼

    Description 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1.除了这 N 座摩天楼外,雅加达市没有其他摩天楼.   有 M 只叫做 “do ...

  6. 洛谷$P3645\ [APIO2015]$雅加达的摩天楼 最短路

    正解:最短路 解题报告: 传送门$QwQ$ 考虑暴力连边,发现最多有$n^2$条边.于是考虑分块 对于长度$p_i$小于等于$\sqrt(n)$的边,建立子图$d=p_i$.说下关于子图$d$的定义? ...

  7. 【题解】P3645 [APIO2015]雅加达的摩天楼(分层图最短路)

    [题解]P3645 [APIO2015]雅加达的摩天楼(分层图最短路) 感觉分层图是个很灵活的东西 直接连边的话,边数是\(O(n^2)\)的过不去 然而我们有一个优化的办法,可以建一个新图\(G=( ...

  8. 【BZOJ4070】[Apio2015]雅加达的摩天楼 set+最短路

    [BZOJ4070][Apio2015]雅加达的摩天楼 Description 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1.除了这 N 座摩天楼 ...

  9. luogu P3645 [APIO2015]雅加达的摩天楼 分块 根号分治

    LINK:雅加达的摩天楼 容易想到设\(f_{i,j}\)表示第i个\(doge\)在第j层楼的最小步数. 转移显然是bfs.值得一提的是把初始某层的\(doge\)加入队列 然后转移边权全为1不需要 ...

随机推荐

  1. 6. webshell文件上传分析溯源

    这道题也是借助大佬的帮助才成功,具体我们来看: 既然人家扫描发现后台目录有文件上传,我们也不能落后,顺便拿出了传说中的御剑,并进行一波扫描: 发现了几个比较有用的目录,特别是upload1.php跟u ...

  2. 扩展thinkphp5的redis类方法

    笔者在开发时发现,thinkphp5的自带redis类方法,只有简单的读取缓存.写入缓存的基本方法,远不能满足我们业务的需求.redis本身支持五种数据类型,string(字符串).hash(哈希). ...

  3. 滴滴Booster移动APP质量优化框架 学习之旅 三

    推荐阅读: 滴滴Booster移动App质量优化框架-学习之旅 一 Android 模块Api化演练 不一样视角的Glide剖析(一) 滴滴Booster移动App质量优化框架-学习之旅 二对重复资源 ...

  4. clone分支,修改文件本地commit后, push回原分支失败,处理方法

    从远程clone 一个仓库到本地仓库A后,由于有多个分支,经常需要切换,不同分支区别比较大,切换一下,需要重编译,于是又在本地clone了改动较大的一个分支F到仓库B: 在B仓库改动后,提交到A仓库的 ...

  5. null, undefined 和布尔值

    说明:此类博客来自以下链接,对原内容做了标注重点知识,此处仅供自己学习参考! 来源:https://wangdoc.com/javascript/basic/introduction.html 1.n ...

  6. 前端需要了解的http知识

    一.五层协议1. OSI(Open System Interconnection 开放式系统互联)七层协议 1)应用层 2)表示层 3)会话层 4)传输层 5)网络层 6)数据链接层 7)物理层2. ...

  7. ue4 代码入门

    官网:暴露游戏元素给蓝图 https://docs.unrealengine.com/latest/CHN/Engine/Blueprints/TechnicalGuide/ExtendingBlue ...

  8. Java IO 输入和输出流

    数据流是指一组有顺序的,有起点和终点的字节集合. 最初的版本中,java.io 包中的流只有普通的字节流,即以 byte 为基本处理单位的流.字节流用来读写 8 位的数据,由于不会对数据做任何转换,因 ...

  9. 将RegEx(正则表达式提取器)与JMeter一起使用

    JMeter的,最流行的开源性能测试工具,可以工作正则表达式,用正则表达式提取.正则表达式是一种用于通过使用高级操作提取文本的必需部分的工具.正则表达式在测试Web应用程序时很流行,因为它们可用于验证 ...

  10. Linux —— shell认识与基础命令

    shell 基础 shell路径: /etc/shells 系统shell版本: $SHELL 在父shell中可以调用子shell echo 把指定内容输出到屏幕上 操作选项: -e: 支持反斜杠控 ...