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:组 ...
随机推荐
- Linux用户组相关指令
⒈增加用户组 ①groupadd 用户组名 ⒉删除用户组 ①groupdel 用户组名 ⒊修改用户所在的用户组 ①usermod -g 用户组 用户名 ★用户和用户组的相关文件 ①/etc/passw ...
- 【Python学习笔记】调整matplotlib的图例legend的位置
有时默认的图例位置不符合我们的需要,那么我们可以使用下面的代码对legend位置进行调整. plt.legend(loc='String or Number', bbox_to_anchor=(num ...
- 深入解析内存原理:DRAM的基本原理
前面我们知道了在一个简单的SRAM 芯片中进行读写操作的步骤了,然后我们来了解一下普通的DRAM 芯片的工作情况.DRAM 相对于SRAM 来说更加复杂,因为在DRAM存储数据的过程中需要对于存储的信 ...
- scn 时间
Scn转换成时间: select to_char(scn_to_timestamp(3998591352171),'YYYY-MM-DD HH24:MI:SS') from dual: 时间转换成sc ...
- makefile 中autoload
在openwrt的makefile中经常能看见这样的描述: define KernelPackage/mt7602e CATEGORY:=MTK Properties TITLE:=MTK MT7 ...
- mysql数据库报错:InnoDB: Operating system error number 13 in a file operation
环境:centos6.5 x86_64 启动mysql发现日志报错(日志路径可以查看/etc/my.cnf的配置) 160722 10:34:08 [Note] Found 42570716 of 4 ...
- 关于ajax请求,返回json数据格式
使用servlet测试 后台数据为:返回类型没有设置(方式一) String str = "["+ "{ id:1, pId:0, name:\"可折腾的父节点 ...
- 转载:abstract的方法是否可同时是static,是否可同时是native,是否可同时是synchronized?
原文:http://blog.csdn.net/fhm727/article/details/5222965 1.abstract与static (what) abstract:用来声明抽象方法,抽象 ...
- .netcore 整合 log4net
1.背景 前两天,曾经的一个同事咨询我,怎样将log4net以中间件的形式整合到core里边去.我不假思索的回答,这种问题应该有人做过吧,他说没有.于是,我去博客园搜了下,发现还真没有,全部都是传统. ...
- lr
Action(){ //获取响应结果 web_reg_save_param("system_code", "LB=system_code\":\"&q ...