5288: [Hnoi2018]游戏
5288: [Hnoi2018]游戏
分析:
考虑y<=x的怎么做,那么只能从左边走到右边。我们可以从最右边的点开始,一次确定每个点往右边可以走多少。
L[x],R[x]分别是x向左向右最远走到的位置,初始L[x]=x,R[x]=x。R[n]=n,然后看n-1,如果n-1存在打开n-1这扇门的钥匙,那么说明n-1可以到n,相应的R[n-1]=R[n]。同样的考虑i,如果i可以打开第i扇门,那么R[i]=R[i+1],继续判断如果i可以打开第R[i]扇门,那么R[i]=R[R[i]]……
于是这样可以求出每个往右延伸的范围。复杂度的证明:每扇门只会被打开一次,每个点只会被求扫一次,于是复杂度是$O(n)$
如果y不小于x,考虑怎么做。将两个点之间的边确定方向(如果钥匙在左边,那么边是左->右,否则是右->左),然后对于找到一个点x,它既能向左走也可以向右走,从这个点开始,往左走到的是y,那么x->y这一段和y<=x的性质一样,做法也一样,扫一遍即可,往右走同理。最后处理x,直接暴力处理即可。
复杂度:每个点只会存在于一条链中,暴力处理的点总复杂度是O(n)的。
如果一条边上没有门呢?没法定向了,缩点即可。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype>
#include<set>
#include<vector>
#include<queue>
#include<map>
#define fi(s) freopen(s,"r",stdin);
#define fo(s) freopen(s,"w",stdout);
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
int a[N], b[N];
int n, m, Q; namespace BF1{
int L[], R[]; bool vis[]; vector<int> vec[], d;
void Mark(int x) {
for (int j = ; j < (int)vec[x].size(); ++j) vis[vec[x][j]] = ;
}
void Calc(int x) {
L[x] = R[x] = x;
for (int i = ; i <= n; ++i) vis[i] = ;
for (int i = ; i < (int)d.size(); ++i)
vis[d[i]] = ;
Mark(x);
while () {
if (!vis[R[x]] && !vis[L[x] - ]) break;
if (vis[R[x]]) {
R[x] ++; Mark(R[x]);
}
if (vis[L[x] - ]) {
L[x] --; Mark(L[x]);
}
}
}
void Main() {
for (int i = ; i <= m; ++i) vec[b[i]].push_back(a[i]);
for (int i = ; i <= m; ++i) vis[a[i]] = ;
for (int i = ; i < n; ++i) if (!vis[i]) d.push_back(i);
for (int i = ; i <= n; ++i) Calc(i);
while (Q--) {
int s = read(), t = read();
if (L[s] <= t && t <= R[s]) puts("YES");
else puts("NO");
}
}
} int head[N], fa[N], vis[N], chu[N], nxt[N], pre[N], L[N], R[N], pos[N], En;
vector<int> d;
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
inline void Union(int x,int y) { if (x != y) fa[y] = x;}
inline void add_edge(int x,int y) { x = find(x), y = find(y); chu[x] ++; } void Calc(int x) {
int z = x;
while (z >= && chu[z] != ) z = pre[z]; if (z < ) z = nxt[z];
for (int i = z; i <= x; i = nxt[i]) {
L[i] = i;R[i] = i;
int now = pre[L[i]];
if (now < z) continue;
while (L[i] <= pos[now] && pos[now] <= R[i]) {
L[i] = L[now], now = pre[L[i]];
}
}
z = x;
while (z <= n && chu[z] != ) z = nxt[z]; if (z > n) z = pre[z];
for (int i = z; i >= x; i = pre[i]) {
L[i] = i;R[i] = i;
int now = R[i];
if (nxt[now] > z) continue;
while (L[i] <= pos[now] && pos[now] <= R[i]) {
R[i] = R[nxt[now]], now = R[i];
}
}
while () {
bool f = ;
if (L[x] <= pos[R[x]] && pos[R[x]] <= R[x]) R[x] = nxt[R[x]], f = ;
if (L[x] <= pos[pre[L[x]]] && pos[pre[L[x]]] <= R[x]) L[x] = pre[L[x]], f = ;
if (!f) break;
}
}
void solve() {
for (int i = ; i <= m; ++i) vis[a[i]] = ;
for (int i = ; i <= n; ++i) fa[i] = i;
for (int i = ; i < n; ++i) if (!vis[i]) Union(i, i + );
int last = ;
for (int i = ; i <= n; ++i)
if (find(i) == i) pre[i] = last, nxt[last] = i, last = i;
nxt[last] = n + ; pre[n + ] = last; for (int i = ; i <= m; ++i) {
a[i] = find(a[i]), b[i] = find(b[i]);
if (b[i] <= a[i]) add_edge(a[i], nxt[a[i]]);
else add_edge(nxt[a[i]], a[i]);
pos[a[i]] = b[i];
}
for (int i = ; i <= n; i = nxt[i]) {
if (chu[i] == || (i == nxt[] && chu[i] == ) || (i == pre[n + ] && chu[i] == ))
Calc(i);
}
}
int main() {
n = read(), m = read(), Q = read();
for (int i = ; i <= m; ++i)
a[i] = read(), b[i] = read();
if (n <= && m <= ) { BF1::Main(); return ; }
if (m == ) { while (Q --) puts("YES"); return ; }
solve();
for (int i = ; i <= n; ++i) if (!L[i]) L[i] = L[find(i)];
for (int i = n; i >= ; --i) if (R[i]) R[i] = nxt[R[i]] - ;
for (int i = ; i <= n; ++i) if (!R[i]) R[i] = R[find(i)]; while (Q--) {
int s = read(), t = read();
if (L[s] <= t && t <= R[s]) puts("YES");
else puts("NO");
}
return ;
}
代码:
5288: [Hnoi2018]游戏的更多相关文章
- bzoj 5288: [Hnoi2018]游戏
Description Solution 乱搞能A的题,毁我青春 记忆化一下扩展过程 只要不是从 \(1\) 枚举到 \(n\) 去扩展都可以 \(AC\) 于是 \(random\_shuffle\ ...
- 【BZOJ5288】[HNOI2018]游戏(拓扑排序)
[BZOJ5288][HNOI2018]游戏(拓扑排序) 题面 BZOJ 洛谷 题解 去年省选的时候这题给我乱搞整过去整过去了,也是虐心了.... 所以当然是来讲正儿八经的正确做法啦. 很明显,我们需 ...
- BZOJ.5288.[AHOI/HNOI2018]游戏(思路 拓扑)
BZOJ LOJ 洛谷 考虑如何预处理每个点能到的区间\([l,r]\). 对于\(i,i+1\)的一扇门,如果钥匙在\(i\)的右边,连边\(i\to i+1\),表示从\(i\)出发到不了\(i+ ...
- 【BZOJ5288】[HNOI2018]游戏(乱搞?)
[BZOJ5288][HNOI2018]游戏(乱搞?) 题面 BZOJ 洛谷 题面自己到洛谷上看把 题解 考场上乱搞拿到了\(90\)分,简直不敢相信. 回家把代码再交了一份直接就\(AC\)了??? ...
- [HNOI2018]游戏[拓扑排序]
题意 题目链接 分析 先将没有锁的房间缩点,首先有一个 \(O(n^2)\) 的想法:从每个点出发,每次检查能否向两边扩张. 容易发现门和门之间如果有锁,必然只有一方能够开锁(只有一把钥匙),并且能够 ...
- 【比赛】HNOI2018 游戏
考试的时候线段树区间查询的return条件打成了l==r....于是光荣爆20(线段树都不会打了?) 看膜博士的题解 #include<bits/stdc++.h> #define ui ...
- [BZOJ5288][HNOI2018]游戏(拓扑排序)
传送门:https://www.luogu.org/problemnew/show/P4436 20分的暴力加一个Random_shuffle就A了.我还能说什么.. 不过这个也不是毫无道理,复杂度应 ...
- bzoj5288: [Hnoi2018]游戏
我还是太年轻了... 考场上就是直接枚举预处理当前位置左右延伸到的最远距离,好像是水了20.. 然后噶爷爷居然随机一下就AC了????mengbier #include<cstdio> # ...
- # HNOI2012 ~ HNOI2018 题解
HNOI2012 题解 [HNOI2012]永无乡 Tag:线段树合并.启发式合并 联通块合并问题. 属于\(easy\)题,直接线段树合并 或 启发式合并即可. [HNOI2012]排队 Tag:组 ...
随机推荐
- np.savetxt()——将array保存到txt文件,并保持原格式
问题:1.如何将array保存到txt文件中?2.如何将存到txt文件中的数据读出为ndarray类型? 需求:科学计算中,往往需要将运算结果(array类型)保存到本地,以便进行后续的数据分析. 解 ...
- 求web前端面试题库及答案
1.对WEB标准以及W3C的理解与认识 标签闭合.标签小写.不乱嵌套.提高搜索机器人搜索几率.使用外 链css和js脚本.结构行为表现的分离.文件下载与页面速度更快.内容能被更多的用户所访问.内容能被 ...
- oem 重建
OracleDBControl启动失败to local from URL=http://your-url.co 方法: emca -deconfig dbcontrol db -repos d ...
- Android APP—— 开发入门教程
一.SDK下载 下载:adt-bundle-windows-x86_64-20140702.zip(20140702 已经是最后版本了) 解压出来如下: 点击Eclipse安装 创建一个新的工作空间安 ...
- centos6.5环境通达OA数据库mysql5.0.67升级至mysql5.5.48方案
centos6.5环境通达OA数据库mysql5.0.67升级至mysql5.5.42方案 整体方案: 环境准备,在备用服务器安装mysql5.5数据库 1.停用生产环境的应用访问 直接修改web的访 ...
- win7设置固定IP
正文: 你必须知道你的路由器网关,一般是192.168.1.1(或192.168.0.1) 按传统的来:开始——控制面板——网络和共享中心——更改适配器设置.一般来讲,这里应该有两个图标,一个是有线网 ...
- 安装最新版的2016版Pycharm后,激活码
2016年安装Pycharm后,过段时间过期.亲测只需要复制以下激活码可以完美解决激活问题,又可以开心的写Python了.以下为激活码内容: BIG3CLIK6F-eyJsaWNlbnNlSWQiOi ...
- 关于Java Web应用中的配置部署描述符web.xml
一.web.xml概述 位于每个Web应用的WEB-INF路径下的web.xml文件被称为配置描述符,这个 web.xml文件对于Java Web应用十分重要,每个Java Web应用都必须包含一个w ...
- Go语言规格说明书 之 变量声明(Variable/Short variable declarations)
go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,完整的介绍Go语 ...
- PYTHON-流程控制之if/while/for
内容: 流程控制: 1. if 2. while 3. for ==================================流程控制之if判断 1 什么是if判断 判断一个条件如果成立则做.. ...