BZOJ4070 [Apio2015]雅加达的摩天楼 【分块 + 最短路】
题目链接
题解
考虑暴力建图,将每个\(B_i\)向其能到的点连边,复杂度\(O(\sum \frac{n}{p_i})\),当\(p\)比较小时不适用
考虑优化建图,每个\(doge\)能移动的点实际上是一组模\(p\)同余的点,那么只要对每个\(p\)建\(n\)个点,然后内部距离为\(p\)的点连边,然后每个点向原来的点连边,如果某个点有步长为\(p\)的\(doge\),则原点向该点连边,这样子每一层点数和边数都是\(O(n)\)的,复杂度是\(O(pn)\),当\(p\)较小时使用
如此可以得出最终算法,分块处理
对于\(p\)较小的点优化建图,\(p\)较大的点暴力建图
跑最短路即可
如果是\(dijsktra\),复杂度\(O(n\sqrt{n}log(n\sqrt{n}))\)
但据说这里\(spfa\)快?
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 4000005,maxm = 15000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int h[maxn],ne = 1;
struct EDGE{int to,nxt,w;}ed[maxm];
inline void build(int u,int v,int w){
ed[++ne] = (EDGE){v,h[u],w}; h[u] = ne;
}
int n,m,B,d[maxn],inq[maxn],S,T;
queue<int> q;
void spfa(){
int E = B * n + n;
for (int i = 1; i <= E; i++) d[i] = INF;
d[S] = 0; q.push(S); int u;
while (!q.empty()){
u = q.front(); q.pop(); inq[u] = false;
Redge(u) if (d[to = ed[k].to] > d[u] + ed[k].w){
d[to] = d[u] + ed[k].w;
if (!inq[to]) q.push(to),inq[to] = true;
}
}
}
int main(){
n = read(); m = read(); B = min((int)sqrt(n),100);
for (int i = 1; i <= B; i++){
for (int j = 1; j <= i; j++){
for (int u = j; u + i <= n; u += i){
build(i * n + u,i * n + u + i,1);
build(i * n + u + i,i * n + u,1);
}
}
for (int j = 1; j <= n; j++)
build(i * n + j,j,0);
}
int x,p;
for (int t = 1; t <= m; t++){
x = read() + 1; p = read();
if (t == 1) S = x;
if (t == 2) T = x;
if (p > B){
for (int i = p,j = 1; x - i > 0; i += p,j++)
build(x,x - i,j);
for (int i = p,j = 1; x + i <= n; i += p,j++)
build(x,x + i,j);
}
else build(x,p * n + x,0);
}
spfa();
if (d[T] == INF) puts("-1");
else printf("%d\n",d[T]);
return 0;
}
BZOJ4070 [Apio2015]雅加达的摩天楼 【分块 + 最短路】的更多相关文章
- [APIO2015] 雅加达的摩天楼 (分块,最短路)
题目链接 Solution 分块+\(Dijkstra\). 难点在于建边,很明显 \(O(n^2)\) 建边会挂一堆 . 那么考虑一下, \(n^2\) 建边多余的是哪些东西 \(???\) 很显然 ...
- 【BZOJ4070】[Apio2015]雅加达的摩天楼 set+最短路
[BZOJ4070][Apio2015]雅加达的摩天楼 Description 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1.除了这 N 座摩天楼 ...
- luogu P3645 [APIO2015]雅加达的摩天楼 分块 根号分治
LINK:雅加达的摩天楼 容易想到设\(f_{i,j}\)表示第i个\(doge\)在第j层楼的最小步数. 转移显然是bfs.值得一提的是把初始某层的\(doge\)加入队列 然后转移边权全为1不需要 ...
- 洛谷P3645 [APIO2015]雅加达的摩天楼(最短路+分块)
传送门 这最短路的建图怎么和网络流一样玄学…… 一个最朴素的想法是从每一个点向它能到达的所有点连边,边权为跳的次数,然后跑最短路(然而边数是$O(n^2)$除非自创复杂度比spfa和dijkstra还 ...
- BZOJ 4070 [Apio2015]雅加达的摩天楼 ——分块 SPFA
挺有趣的分块的题目. 直接暴力建边SPFA貌似是$O(nm)$的. 然后考虑分块,$\sqrt n$一下用虚拟节点辅助连边, 以上的直接暴力连边即可. 然后卡卡时间,卡卡空间. 终于在UOJ上T掉辣. ...
- 【题解】P3645 [APIO2015]雅加达的摩天楼(分层图最短路)
[题解]P3645 [APIO2015]雅加达的摩天楼(分层图最短路) 感觉分层图是个很灵活的东西 直接连边的话,边数是\(O(n^2)\)的过不去 然而我们有一个优化的办法,可以建一个新图\(G=( ...
- BZOJ 4070:[APIO2015]雅加达的摩天楼 最短路
4070: [Apio2015]雅加达的摩天楼 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 464 Solved: 164[Submit][Sta ...
- bzoj 4070 [Apio2015]雅加达的摩天楼 Dijkstra+建图
[Apio2015]雅加达的摩天楼 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 644 Solved: 238[Submit][Status][D ...
- 【bzoj4070】[Apio2015]雅加达的摩天楼 set+堆优化Dijkstra
题目描述 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1.除了这 N 座摩天楼外,雅加达市没有其他摩天楼. 有 M 只叫做 “doge” 的神秘生物 ...
随机推荐
- dubbo常见的一些面试题
什么是Dubbo? Duubbo是一个RPC远程调用框架, 分布式服务治理框架 什么是Dubbo服务治理? 服务与服务之间会有很多个Url.依赖关系.负载均衡.容错.自动注册服务. Dubbo有哪些协 ...
- Oracle同义词和序列
同义词:是表.索引.视图的模式对象的一个别名,通过模式对象创建同意词,可以隐藏对象的实际名称和 所有者信息,为对象提供一定的安全性,开发应用程序时:应该尽量避免直接使用表,视图 或其他对象,改用对象的 ...
- .net core 2.1.3可能引发Could not load file or assembly XXXXX的错误
参考文档: https://github.com/aspnet/Home/issues/3503 写在前面 感觉自己现在干的活离开发越来越远了啊,不过也很好,每天能学到不少东西,中文的,英文的,永远也 ...
- VLP16线用户手册.md
VLP16线用户手册 文档 传感器数据 分组类型和定义 传感器产生两种类型的数据包:数据包和位置数据包.位置包有时也被称为遥测包或GPS包. 数据包包括传感器测量到的三维数据以及返回光脉冲的表面的校 ...
- Python爬虫入门(6):Cookie的使用
为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密) 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓 ...
- 软件工程 speedsnail 第二次冲刺10
20150527 完成任务:蜗牛碰到线后速度方向的调整:已经基本实现多方向的反射: 遇到问题: 问题1 反射角的问题 解决1 利用tan()三角函数 明日任务: 大总结.找到新问题.布置下一次冲刺方案
- lintcode-491-回文数
491-回文数 判断一个正整数是不是回文数. 回文数的定义是,将这个数反转之后,得到的数仍然是同一个数. 注意事项 给的数一定保证是32位正整数,但是反转之后的数就未必了. 样例 11, 121, 1 ...
- prototype.js中Function.prototype.bind方法浅解
prototype.js中的Function.prototype.bind方法: Function.prototype.bind = function() { var __method = this; ...
- 初识 es6
es6 可能出来已经有一段时间了,但是我到今天才发现他的好,却不是很了解他,也不知道各个浏览器的兼容性怎么样?今天就把他们都弄明白. 新增命令 let ES6新增了let命令,用来声明变量.它的用法类 ...
- 使用Kettle导出excel
1.开发背景 在web项目中,经常会需要查询数据导出excel,以前比较常见的就是用poi.使用poi的时候也有两种方式,一种就是直接将集合一次性导出为excel,还有一种是分批次追加的方式适合数据量 ...