Description

题库链接

有 \(n\) 个房间排成一列,编号为 \(1,2,...,n\) ,相邻的房间之间都有一道门。其中 \(m\) 个门上锁,其余的门都能直接打开。现在已知每把锁的钥匙在哪个房间里(每把锁有且只有一把钥匙与之对应)。

现给出 \(p\) 个询问:询问从房间 \(S\) 出发是否能到达房间 \(T\) 。

\(1\le n,p\le 10^6\) , \(0\le m <n\) 。

Solution

推推性质,显然对于每个起点,它能到达的区域一定是一个完整的区间。

\(O(n^2)\) 比较容易搞的,稍微转化一下,把一些约束关系建成图,将与钥匙同侧的房间连边到钥匙所在的房间,钥匙所在的房间连边到异侧的房间。

显然图是具有层次性的,那我可以把最底层的暴力跑出来,逐步上推,每一次都可以利用下一层的信息。

似乎能做到 \(O(n)\) 。考场上想到可能这样的约束关系可能成环(似乎不会),于是还打了个 \(tarjan\) 。因为成环的话,同一个环内的点的“层次”是相同的。

Code

#include <bits/stdc++.h>
#define pb push_back
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
using namespace std;
const int N = 1e6+5;
int read() {
int sum = 0; char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') sum = (sum<<1)+(sum<<3)+ch-'0', ch = getchar();
return sum;
}
int n, m, p, d[N], l[N], r[N], q[N], head, tail, in[N];
int dfn[N], low[N], times, S[N], vis[N], sccno[N], sccnum;
vector<int>to[N], scc[N];
struct tt {int to, next; }edge[N<<1];
int path[N], top; void tarjan(int u) {
low[u] = dfn[u] = ++times; S[++top] = u, vis[u] = 1;
for (int i = path[u]; i; i = edge[i].next) {
int v = edge[i].to;
if (!dfn[v]) {
tarjan(v); low[u] = min(low[u], low[v]);
}else if (vis[v]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u]) {
++sccnum; int v = 0;
do {
v = S[top--]; scc[sccnum].pb(v);
sccno[v] = sccnum; vis[v] = 0;
}while(u != v);
}
}
void topsort() {
for (int i = 1; i <= sccnum; i++) {if (!in[i]) q[tail++] = i; }
while (head < tail) {
int u = q[head++];
for (int i = 0, sz = to[u].size(); i < sz; i++) {
int v = to[u][i];
--in[v]; if (!in[v]) q[tail++] = v;
}
}
}
void solve(int x) {
int L = x, R = x;
while (true) {
if (R != n && (d[R] >= L && d[R] <= R || d[R] == 0)) {++R, L = Min(L, l[R]), R = Max(R, r[R]); continue; }
if (L != 1 && (d[L-1] >= L && d[L-1] <= R || d[L-1] == 0)) {--L; L = Min(L, l[L]), R = Max(R, r[L]); continue; }
break;
}
l[x] = L, r[x] = R;
}
void add(int u, int v) {edge[++top].to = v, edge[top].next = path[u]; path[u] = top; }
void work() {
n = read(), m = read(), p = read();
for (int i = 1, x, y; i <= m; i++) {
x = read(), y = read(); d[x] = y;
if (y <= x) {
if (x != y) add(x, y);
add(y, x+1);
}else {
if (x+1 != y) add(x+1, y);
add(y, x);
}
}
top = 0;
for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i);
for (int u = 1; u <= n; u++)
for (int i = path[u]; i; i = edge[i].next)
if (sccno[u] != sccno[edge[i].to])
to[sccno[u]].pb(sccno[edge[i].to]), ++in[sccno[edge[i].to]];
topsort();
for (int i = 1; i <= n; i++) l[i] = n+1;
for (int i = sccnum-1; i >= 0; i--) {
int u = q[i];
for (int i = 0, sz = scc[u].size(); i < sz; i++)
solve(scc[u][i]);
}
int s, t;
while (p--) {
s = read(), t = read();
if (l[s] <= t && r[s] >= t) puts("YES");
else puts("NO");
}
}
int main() {work(); return 0; }

[HNOI 2018]游戏的更多相关文章

  1. 【HNOI 2018】游戏

    Problem Description 一次小 \(G\) 和小 \(H\) 在玩寻宝游戏,有 \(n\) 个房间排成一列,编号为 \(1,2,-,n\),相邻房间之间都有 \(1\) 道门.其中一部 ...

  2. 【HNOI 2018】寻宝游戏

    Problem Description 某大学每年都会有一次 \(Mystery\ Hunt\) 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为新 ...

  3. [HNOI 2018]寻宝游戏

    Description 题库链接 给出 \(n\) 个 \(m\) 位的二进制数,在每一个二进制数间插入一个 & 或 | ,第 \(0\) 个数为 \(0\) , \(0,1\) 间也要插入符 ...

  4. 【题解】Luogu P4436 [HNOI/AHOI2018]游戏

    原题传送门 \(n^2\)过百万在HNOI/AHOI2018中真的成功了qwqwq 先将没门分格的地方连起来,枚举每一个块,看向左向右最多能走多远,最坏复杂度\(O(n^2)\),但出题人竟然没卡(建 ...

  5. HNOI 2018 简要题解

    寻宝游戏 毒瘤题. 估计考试只会前30pts30pts30pts暴力然后果断走人. 正解是考虑到一个数&1\&1&1和∣0|0∣0都没有变化,&0\&0& ...

  6. [洛谷P4436] HNOI/AHOI2018 游戏

    问题描述 一次小G和小H在玩寻宝游戏,有n个房间排成一列,编号为1,2,...,n,相邻的房间之间都有一道门.其中一部分门上锁(因此需要有对应的钥匙才能开门),其余的门都能直接打开.现在小G告诉了小H ...

  7. [HNOI 2018]道路

    Description 题库链接 给出一棵含有 \(n\) 个叶子节点的二叉树,对于每个非叶子节点的节点,其与左儿子相连的边为公路,其与右儿子相连的边为铁路.对于每个节点,选择一条与其儿子相连的铁路或 ...

  8. [HNOI 2018]排列

    Description 题库链接 给定 \(n\) 个整数 \(a_1, a_2, \dots, a_n, 0 \le ai \le n\) ,以及 \(n\) 个整数 \(w_1, w_2, \do ...

  9. [HNOI/AHOI2018]游戏

    题目描述 https://lydsy.com/JudgeOnline/upload/201804/%E6%B9%96%E5%8D%97%E4%BA%8C%E8%AF%95%E8%AF%95%E9%A2 ...

随机推荐

  1. 2017级C语言教学总结

    一个学期下来,对于这门课教学还是感受挺多,多个教学平台辅助,确实和我前10年的教学方式区别很多,也辛苦很多. 一.课堂教学方面 1.课堂派预习作业 主要借助课堂派平台,每次课前发布预习作业.而预习作业 ...

  2. Beta阶段报告

    Beta版测试报告 1. 在测试过程中总共发现了多少Bug?每个类别的Bug分别为多少个? BUG名 修复的BUG 不能重现的BUG 非BUG 没能力修复的BUG 下个版本修复 url乱码 √ 手机端 ...

  3. 项目Beta冲刺第一天

    1.昨天的困难,今天解决的进度,以及明天要做的事情 昨天的困难:企业自查风险模块仍旧存在部分问题,没有什么大的困难,主要是需求问题,企业人员什么条件之下可以添加风险点,第三方评估人员是否可以上报风险, ...

  4. 团队作业7——第二次项目冲刺(Beta版本12.08)

    项目每个成员的进展.存在问题.接下来两天的安排. 已完成的内容:完成了排行榜的测试.上传头像功能的原型设计.界面优化 计划完成的内容:上传头像功能开发.测试.头像裁剪原型设计 每个人的工作 (有wor ...

  5. :after/:before使用技巧

    伪类:after/:before基本使用 div:before{ content:'';//必须要写,没写则伪元素无效 display:; position:''; ... } //在一个div子元素 ...

  6. 有货前端 Web-APM 实践

    有货前端 Web-APM 实践 0 背景 有货电商技术架构上采用的是前后端分离,前端是主要以业务展示和接口聚合为主,拥有自己的 BFF (Backend For Frontend),以 nodejs ...

  7. Python内置函数(5)——pow

    英文文档: pow(x, y[, z]) Return x to the power y; if z is present, return x to the power y, modulo z (co ...

  8. SpringCloud的DataRest(三)

    一.进阶配置定义 二.定制显示内容和控制方法使用 1.控制显示的内容 如果想让输出显示的数据始终按我们定义的格式显示: 配置之后返回的JSON数据会按照ListApp定义的数据格式进行输出 2.屏蔽自 ...

  9. 离线Chrome插件安装文件(crx)的安装方法

    离线Chrome插件安装文件(crx)的安装方法 一.正常安装方法 1.开发谷歌浏览器,设置->扩展程序 在打开的谷歌浏览器的扩展管理器中用户可以看到一些已经安装程序的Chrome插件,或者一个 ...

  10. websocketj--随时随地在Web浏览器中操作你的服务端程序

    0 - 有没有觉得Linux标准终端界面输入输出枯燥无味? 1 - 什么?vmstat命令的输出数据不直观?有没有想过能够可视化该命令的输出? 2 - 尝试过用浏览器操作Windows中的cmd吗? ...