Luogu P4436 [HNOI/AHOI2018]游戏
时间:2019-11-26
本文章向大家介绍Luogu P4436 [HNOI/AHOI2018]游戏,主要包括Luogu P4436 [HNOI/AHOI2018]游戏使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目
我们要求出\(l_i,r_i\)表示\(i\)最远能够到达的最左边和最右边的格子。
首先有一个比较简单的暴力,就是每次我们选择一个格子,然后从当前格子开始往左右暴力扩展,找到能够到达的最远的格子。
然后对于这个暴力,我们有一个小小的优化:就是假如我们从左往右处理,当前的点是\(i\),新扩展到了一个左边的节点\(j\),那么我们可以直接拿\(l_j\)赋给\(l_i\),如此重复。右边同理。
这样的暴力是可以被卡成\(O(n^2)\)的。但是题目数据水所以可以通过。
现在我们通过一些优化来使得这个暴力的复杂度变得正确。
对于一段连续的没有门的格子,我们可以把它缩成一个格子。
然后对于一个门和钥匙\((x,y)\),如果\(y>x\),我们就从\(x\)到\(x+1\)建一条边,意思是无法从\(x\)走到\(x+1\),\(y<x\)同理。
这样我们再拓扑排序,因为点\(u\)的答案区间一定不会包含拓扑序在它后面的点的答案区间,所以按照拓扑序转移就能够保证复杂的正确性了,最后复杂度为\(O(n+m)\)。
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO
{
char ibuf[(1<<21)+1],*iS,*iT;
char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
}
using namespace IO;
const int N=1000007;
vector<int>E[N];queue<int>q;
int n,m,Q,x[N],y[N],pos[N],cnt=1,l[N],r[N],f[N],deg[N],bel[N];
void add(int u,int v){E[u].pb(v),++deg[v];}
int check(int x,int y)
{
if(!y||y==cnt+1) return 0;
if(x<y) --y;
return l[x]<=pos[y]&&pos[y]<=r[x];
}
void toposort()
{
for(int i=1;i<=cnt;++i) if(!deg[i]) q.push(i);
for(int u,f;!q.empty();)
{
u=q.front(),q.pop(),f=1;
while(f)
{
f=0;
while(check(u,l[u]-1)) l[u]=l[l[u]-1],f=1;
while(check(u,r[u]+1)) r[u]=r[r[u]+1],f=1;
}
for(int v:E[u]) if(!(--deg[v])) q.push(v);
}
}
int main()
{
n=read(),m=read(),Q=read();
for(int i=1;i<=m;++i) x[i]=read(),y[i]=read(),f[x[i]]=1;
f[n]=1;
for(int i=1;i<=n;++i) if(bel[i]=cnt,f[i]) l[cnt]=r[cnt]=cnt,++cnt;
--cnt;
for(int i=1,u,v;i<=m;++i)
{
u=bel[x[i]],v=bel[y[i]],pos[u]=v;
if(v<=u) add(u+1,u); else add(u,u+1);
}
toposort();
for(int u,v;Q;--Q) u=bel[read()],v=bel[read()],puts(l[u]<=v&&v<=r[u]? "YES":"NO");
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11936499.html
- 手把手带你进入TOP20的商超销售预测
- 【干货荟萃】机器学习&深度学习知识资料大全集(二)(论文/教程/代码/书籍/数据/课程等)
- 逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能
- 【专知-Java Deeplearning4j深度学习教程06】用卷积神经网络CNN进行图像分类
- 万恶的剪贴板==》为存储而生
- AdaBoost算法(R语言)
- CTF---Web入门第六题 因缺思汀的绕过
- 小案例(六):预测小偷行为(python)
- 小案例(五):销量预测(python)
- SQL:插入指定标识列的数据时候的小错误
- 逻辑回归与梯度下降详解
- 决策树(R语言)
- ExecuteReader在执行有输出参数的存储过程时拿不到输出参数
- CTF---Web入门第十三题 拐弯抹角
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP中的类
- PHP获取表单textarea数据中的换行问题
- Numpy根据Bool值挑选数组中元素
- MySQL获取每个分类下面的前三条数据
- windows宿主机如何SSH连接VMware的Linux虚拟机
- np.random.rand均匀分布随机数和np.random.randn正态分布随机数函数使用方法
- Java FileReader使用相对路径读取文件
- MySQL批量插入数据库实现语句性能分析
- np.repeat用法
- MySQL优化INSERT的性能
- PHP在函数体中传递与接收参数
- 使用Arraylist将数组中元素随机均等乱序分为N个子数组
- PHP中abstract 和 interface的区别
- PHP5中的魔术方法
- 一起来学演化计算-matlab基本函数randn,rand, orth