BZOJ 5097: [Lydsy1711月赛]实时导航(最短路 + bitset)
题意
\(n\) 个点的有向图,边权 \(\in \{1, 2, 3, 4\}\) ,\(m\) 次修改边权/加边/删边,\(q\) 次询问:以 \(s_i\) 为起点,输出它到其他点的最短路。
\(n ≤ 5 \times 10^2 ,m \le 5 \times 10^4 , q \le 5 \times 10^3\)
题解
这图很密,如果修改就做一遍 \(Dijsktra\) 是 \(O((n + m) \log n)\) 的复杂度,显然是过不去的。
但是发现边权似乎不大,我们考虑把这些要进来的点压到 std :: bitset<N> 里面。
也就是我们维护到当前距离为 \(1, 2, 3, 4\) 的队列,然后我们把图也可以用 std :: bitset<N> 存下来。
然后每次就把要进来的点 或(or)上当前维护队列就行了,每次就循环移位就可以了。
然后每次取 std :: bitset<N> 的元素就行了,这里有两个骚操作 _Find_first() 以及 _Find_next(u) ,可以快速查找 std :: bitset<N> 的元素。
最后复杂度就是 \(\displaystyle O(\frac{qn^2}{\omega} + m)\) 的,看起来很科学qwq
总结
对于稠密图,可以考虑用 std :: bitset 来优化复杂度,加快暴力操作。
然后对于边权小,可以考虑用普通队列来替代优先队列,常常会得到更优秀的复杂度。
代码
具体看代码操作就行了。
/**************************************************************
Problem: 5097
User: zjp_shadow
Language: C++
Result: Accepted
Time:10624 ms
Memory:2440 kb
****************************************************************/
#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
template<typename T> inline bool chkmin(T &a, T b) {return b < a ? a = b, 1 : 0;}
template<typename T> inline bool chkmax(T &a, T b) {return b > a ? a = b, 1 : 0;}
inline int read() {
int x(0), sgn(1); char ch(getchar());
for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return x * sgn;
}
void File() {
#ifdef zjp_shadow
freopen ("5097.in", "r", stdin);
freopen ("5097.out", "w", stdout);
#endif
}
const int N = 510;
int val[N][N];
typedef bitset<N> Info;
Info G[N][4]; int dis[N], que[N], len, n, m;
void Bfs(int S) {
Info Q[4];
For (i, 0, 3) Q[i] = G[S][i];
Set(dis, 0); dis[S] = -1;
for (int cur = 0, tim = 1, o = 0; cur < 5; ++ tim, o = (o + 1) % 4) {
len = 0;
for (int v = Q[o]._Find_first(); v < (int)Q[o].size(); v = Q[o]._Find_next(v)) {
Q[o][v] = false; if (!dis[v]) que[++ len] = v;
}
For (i, 1, len) {
int u = que[i]; dis[u] = tim;
Q[(o + 1) % 4] |= G[u][0];
Q[(o + 2) % 4] |= G[u][1];
Q[(o + 3) % 4] |= G[u][2];
Q[o] |= G[u][3];
}
cur = !len ? cur + 1 : 0;
}
int ans = 0;
For (i, 1, n) if (i != S)
ans += i * dis[i];
printf ("%d\n", ans);
}
int main () {
File();
n = read(); m = read();
For (i, 1, n) For (j, 1, n) {
int w = read(); val[i][j] = w;
if (w) G[i][w - 1][j] = true;
}
For (i, 1, m) {
char opt[5];
scanf ("%s", opt + 1);
if (opt[1] == 'Q') Bfs(read());
else {
int u = read(), v = read(), w = read();
if (val[u][v]) G[u][val[u][v] - 1][v] = false;
val[u][v] = w;
if (w) G[u][w - 1][v] = true;
}
}
return 0;
}
BZOJ 5097: [Lydsy1711月赛]实时导航(最短路 + bitset)的更多相关文章
- bzoj 5092 [Lydsy1711月赛]分割序列 贪心高维前缀和
[Lydsy1711月赛]分割序列 Time Limit: 5 Sec Memory Limit: 256 MBSubmit: 213 Solved: 97[Submit][Status][Dis ...
- bzoj 5094 [Lydsy1711月赛]硬盘检测 概率dp
[Lydsy1711月赛]硬盘检测 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 273 Solved: 75[Submit][Status][Dis ...
- bzoj 5093 [Lydsy1711月赛]图的价值 NTT+第二类斯特林数
[Lydsy1711月赛]图的价值 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 245 Solved: 128[Submit][Status][D ...
- bzoj 5092: [Lydsy1711月赛]分割序列
5092: [Lydsy1711月赛]分割序列 Time Limit: 5 Sec Memory Limit: 256 MBSubmit: 219 Solved: 100[Submit][Stat ...
- BZOJ 5093[Lydsy1711月赛]图的价值 线性做法
博主曾更过一篇复杂度为$O( k· \log k)$的多项式做法在这里 惊闻本题有$ O(k)$的神仙做法,说起神仙我就想起了于是就去学习了一波 幂与第二类斯特林数 推导看这里 $$ x^k=\sum ...
- BZOJ 5093: [Lydsy1711月赛]图的价值
第二类斯特林数模版题 需要一些组合数的小$ trick$ upd:这里更新了本题巧妙的$ O(k)$做法,虽然常数很大就是了 传送门:here 题意:求所有$ n$个节点的无重边自环图的价值和,定义一 ...
- BZOJ.5092.[Lydsy1711月赛]分割序列(高维前缀和)
题目链接 \(Description\) \(Solution\) 首先处理\(a_i\)的前缀异或和\(s_i\).那么在对于序列\(a_1,...,a_n\),在\(i\)位置处分开的价值为:\( ...
- BZOJ.5093.[Lydsy1711月赛]图的价值(NTT 斯特林数)
题目链接 对于单独一个点,我们枚举它的度数(有多少条边)来计算它的贡献:\[\sum_{i=0}^{n-1}i^kC_{n-1}^i2^{\frac{(n-2)(n-1)}{2}}\] 每个点是一样的 ...
- 【刷题】BZOJ 5091 [Lydsy1711月赛]摘苹果
Description 小Q的工作是采摘花园里的苹果.在花园中有n棵苹果树以及m条双向道路,苹果树编号依次为1到n,每条道路的两端连接着两棵不同的苹果树.假设第i棵苹果树连接着d_i条道路.小Q将会按 ...
随机推荐
- Minimal string CodeForces – 797C
题目链接 题目难度: 1700rating 题目类型:string+贪心+STL 题目思路: 由于题目要求的最终结果是字典序最小的那个字符串,那么我们从贪心的从’a’开始查找字符串里是否存在,如果存在 ...
- Telnet服务器和客户端请求处理
Telnet服务器和客户端请求处理 本文的控制台项目是根据SuperSocket官方Telnet示例代码进行调试的,官方示例代码:Telnet示例. 开始我的第一个Telnet控制台项目之旅: 创建控 ...
- python自动化常见问题汇总
1.如何提高selenium脚本的执行速度? Selenium脚本的执行速度受多方面因素的影响,如网速,操作步骤的繁琐程度,页面加载的速度,以及我们在脚本中设置的等待时间,运行脚本的线程 ...
- "errcode":40163,"errmsg":"code been used...报错,做PC微信登录时出现code been used...报错问题
这是一个坑,一个巨坑,一个恶心的坑 出现这个问题的大概意思就是微信回调了两次登录接口,code使用了两次,而在微信官方文档上写着code只能用一次,用来获取access_token,但我TM看着就糊涂 ...
- flutter中使用svg
dependencies: flutter_svg: ^0.12.1 flutter packages get import 'package:flutter_svg/flutter_svg.dart ...
- mysql定时任务event——清理过期数据
需要删除数据的表名:t_req_log 建表sql CREATE TABLE `t_req_log` ( `id` ) NOT NULL AUTO_INCREMENT, `host` ) DEFAUL ...
- com.alibaba的fastjson简介
fastjson简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库.它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSO ...
- thinkphp5 实现搜索分页能下一页保留搜索条件
正常情况下: 搜索后分页了,点击第二页,进入页面之前的搜索条件没有了. 如代码 $keywords=$this->request->param('keywords'); $this-> ...
- telerik reporting报表
Telerik Reporting是一个非常人性化的控件,一个报表的生成几乎不用写代码,都是通过"所见即所得"模式完成.由于客户需要在实际的项目中运用Telerik Reporti ...
- C# 获取文件详细备注信息 (如图片、视频实际创建时间)
在整理照片/视频时想根据实际拍摄时间重命名文件,但 System.IO.FileInfo 只能获取到文件的创建时间或最后写入时间,不符合要求,遂寻找解决方案 方案 1: System.Drawing ...