[HNOI2018]游戏[拓扑排序]
题意
分析
- 先将没有锁的房间缩点,首先有一个 \(O(n^2)\) 的想法:从每个点出发,每次检查能否向两边扩张。
- 容易发现门和门之间如果有锁,必然只有一方能够开锁(只有一把钥匙),并且能够开一扇门的位置一定是一个区间 \([l,r]\)。假设门 \(p<l\) ,则区间内的所有门都为 \(\leftarrow\) 。如果扩展顺序为 \(l\) 到 \(r\) 就可以保证对于开 \(p\) 门这个操作只被进行一次,而后面的位置可以继承这个可行区间。
- 所以如果对于门 \(a\),如果钥匙在 \(a\) 左边,就连边 \(a+1 \rightarrow a\) ,反之同理。按照拓扑序扩展就可以保证扩展次数至多为 \(m\) 次。
- 时间复杂度 \(O(n+m)\) 。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define go(u) for(int i = head[u], v = e[i].to; i; i=e[i].lst, v=e[i].to)
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define pb push_back
#define re(x) memset(x, 0, sizeof x)
inline int gi() {
int x = 0,f = 1;
char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) { x = (x << 3) + (x << 1) + ch - 48; ch = getchar();}
return x * f;
}
template <typename T> inline bool Max(T &a, T b){return a < b ? a = b, 1 : 0;}
template <typename T> inline bool Min(T &a, T b){return a > b ? a = b, 1 : 0;}
const int N = 1e6 + 7;
int n, m, p, ndc;
int x[N], y[N], pos[N], du[N], id[N], L[N], R[N];
bool lck[N];
vector<int>G[N];
queue<int>Q;
void solve() {
rep(i, 1, ndc) L[i] = R[i] = i;
rep(i, 1, ndc) if(!du[i]) Q.push(i);
while(!Q.empty()) {
int u = Q.front();Q.pop();
while(1) {
bool fg = 0;
if(u > 1 && L[u] <= pos[L[u] - 1] && pos[L[u] - 1] <= R[u]) fg = 1, L[u] = L[L[u] - 1];
if(u < ndc && L[u] <= pos[R[u]] && pos[R[u]] <= R[u]) fg = 1, R[u] = R[R[u] + 1];
if(!fg) break;
}
for(auto v:G[u]) {
if(--du[v] == 0) Q.push(v);
}
}
}
int main() {
n = gi(), m = gi(), p = gi();
rep(i, 1, m) {
x[i] = gi(), y[i] = gi();
lck[x[i]] = 1;
}
id[1] = ++ndc;
rep(i, 2, n) {
if(lck[i - 1]) id[i] = ++ndc;
else id[i] = id[i - 1];
}
rep(i, 1, m) pos[id[x[i]]] = id[y[i]];
rep(i, 1, m) {
x[i] = id[x[i]], y[i] = id[y[i]];
if(y[i] <= x[i]) G[x[i] + 1].pb(x[i]), ++du[x[i]];
if(y[i] > x[i]) G[x[i]].pb(x[i] + 1), ++du[x[i] + 1];
}
solve();
while(p--) {
int s = id[gi()], t = id[gi()];
if(L[s] <= t && t <= R[s]) puts("YES");
else puts("NO");
}
return 0;
}
[HNOI2018]游戏[拓扑排序]的更多相关文章
- [BZOJ5288][HNOI2018]游戏(拓扑排序)
传送门:https://www.luogu.org/problemnew/show/P4436 20分的暴力加一个Random_shuffle就A了.我还能说什么.. 不过这个也不是毫无道理,复杂度应 ...
- [BZOJ5289][HNOI2018]排列(拓扑排序+pb_ds)
首先确定将所有a[i]向i连边之后会形成一张图,图上每条有向边i->j表示i要在j之前选. 图上的每个拓扑序都对应一种方案(如果有环显然无解),经过一系列推导可以发现贪心策略与合并的块的大小和w ...
- 【BZOJ5288】[HNOI2018]游戏(拓扑排序)
[BZOJ5288][HNOI2018]游戏(拓扑排序) 题面 BZOJ 洛谷 题解 去年省选的时候这题给我乱搞整过去整过去了,也是虐心了.... 所以当然是来讲正儿八经的正确做法啦. 很明显,我们需 ...
- FZU xxx游戏(拓扑排序+暴力)
xxx游戏 Time Limit: 1000MS Memory Limit: 32768 KB Description 小M最近很喜欢玩XXX游戏.这个游戏很简单,仅由3个场景(分别为1.2. ...
- Problem 1014 xxx游戏 暴力+拓扑排序
题目链接: 题目 Problem 1014 xxx游戏 Time Limit: 1000 mSec Memory Limit : 32768 KB 问题描述 小M最近很喜欢玩XXX游戏.这个游戏很简单 ...
- 拓扑排序 - 并查集 - Rank of Tetris
Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球 ...
- HDU 1811 Rank of Tetris(拓扑排序+并查集)
题目链接: 传送门 Rank of Tetris Time Limit: 1000MS Memory Limit: 32768 K Description 自从Lele开发了Rating系统, ...
- ACM: hdu 1811 Rank of Tetris - 拓扑排序-并查集-离线
hdu 1811 Rank of Tetris Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & % ...
- Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序
题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★ 输入文件:pvz.in 输出文件:p ...
随机推荐
- Elasticsearch5.4署遇到的问题
问题一 can not run elasticsearch as root Elastic 不建议通过root用户启动ES服务器,如果非要用root启动,可以在config/jvm.options配置 ...
- linux查找某段时间修改的文件的总大小
1.统计 2017-10-25 16:30:00 至 2017-10-25 19:30:00 修改的文件的总大小 b= for i in `find -type f \( -newermt '2017 ...
- Sql Server 判断字符串是否可以转数字
主要是在sql server的内置系统函数ISNUMERIC的基础上,将例外的“+”.“-”.“$”等也进行判断. CREATE FUNCTION [dbo].[fn_IsNumberic]( @st ...
- Linux的命名空间详解--Linux进程的管理与调度(二)【转】
Linux Namespaces机制提供一种资源隔离方案. PID,IPC,Network等系统资源不再是全局性的,而是属于特定的Namespace.每个Namespace里面的资源对其他Namesp ...
- Unity 4.6 GUI
一起来窥探Unity的下一代GUI 预览 UI组件 UI结构 Canvas Button Selection List(滑动列表)
- office(Word、Excel、PPT等图标异常和桌面无新建解决方案)
前言吐槽: 前不久因为安装了WPS,然后觉得不好用卸载WPS装回office就出现了一个很恶心的问题:word文档.excel文档.PPT这些办公软件图标异常,显示的是下面这样: 打开倒是可以正常用w ...
- Alpha冲刺! Day3 - 砍柴
Alpha冲刺! Day3 - 砍柴 今日已完成 晨瑶:补充安卓技能树: review接口文档:看了点七牛云安卓API. 昭锡:没有团队项目相关贡献. 永盛: API 文档基本完成:根据 API 文档 ...
- mysql字符串查询常用命令
对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str) 返回字符串str的最左面字符的ASCII代码值.如果str是空字符串,返回0.如果str是NULL,返回NULL. mysql' ...
- python分包写入文件,写入固定字节内容,当包达到指定大小时继续写入新文件
第6行通过 for 循环控制生成 .log 文件的数量 第8行,如果该文件存在时先进行清空,然后再进行写入操作 第13行,将文件大小的单位转为MB 第14行,如果文件大小超过1MB时,跳出当前循环,重 ...
- java 三种循环及注意事项
package debug; public class Demo8 { public static void main(String[] args) { //采用for循环打印10次Java好 for ...