BZOJ5288 & 洛谷4436 & LOJ2508:[HNOI/AHOI2018]游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5288
https://www.luogu.org/problemnew/show/P4436
UPD:重温了一下发现代码只能用C++(NOI)才能过了,不知道原因,但也懒得重写了,反正是对的。
看洛谷题解里面清一色的暴力,连唯一正解也是用了奇技淫巧才过(当然本题解参考了那个题解)。
于是难受的我来简单说一下“正解”(如有错误请指出orz)。
先从暴力开始,对于每个点我们暴力找到其能够到达的最大的区间[l,r]。
一个优化:我们在加入新的点进入这个区间的时候,可以把该点的答案区间合并进区间内。
接下来是正解,首先是对于每个门i,如果钥匙在其左边则add(i+1,i),否则add(i,i+1),其中边的含义是从入点无法到达出点。
于是对这个图拓扑排序后可发现,点u的答案区间一定不包含比其排名大的点,则在暴力优化的帮助下,我们可以证明出需要我们暴力更新的次数只有O(n)次。
但是为什么又要按照那篇题解所说,“初始化序列倒着加会快”呢?
我把数据下载下来才发现一个坑。
对于不在拓扑图上的点,其更新后的答案区间可能会覆盖与它同级甚至比它排名小的点的答案区间,这样暴力优化就无用武之地,复杂度退化到O(n^2)。
所以我们必须缩点,才能保证算法的复杂度。
(话句话讲就是出题人都如此煞费苦心卡掉了复杂度不对的正解却让暴力AC了)
#include<cmath>
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e6+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int to,nxt;
}e[N];
struct data{
int x,y;
}d[N];
int n,m,p,head[N],cnt,id,to[N];
int key[N],l[N],r[N],deg[N];
inline void add(int u,int v){
e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;++deg[v];
}
inline bool pan(int x,int y){
if(y<||y>id)return ;
if(x<y)--y;
return l[x]<=key[y]&&key[y]<=r[x];
}
queue<int>q;
void dfs(){
for(int i=;i<=id;++i)if(!deg[i])q.push(i);
while(!q.empty()){
int u=q.front();q.pop();
bool flag=;
while(flag){
flag=;
while(pan(u,l[u]-))l[u]=l[l[u]-],flag=;
while(pan(u,r[u]+))r[u]=r[r[u]+],flag=;
}
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(!(--deg[v]))q.push(v);
}
}
}
inline void init(){
key[n]=-;id=;
for(int i=;i<=n;++i){
to[i]=id;
if(key[i])l[id]=r[id]=id++;
}--id;
for(int i=;i<=m;++i){
int x=to[d[i].x],y=to[d[i].y];
key[x]=y;
if(x<y)add(x,x+);
else add(x+,x);
}
}
int main(){
n=read(),m=read(),p=read();
for(int i=;i<=m;++i){
d[i].x=read(),d[i].y=read();
key[d[i].x]=d[i].y;
}
init();dfs();
for(int i=;i<=p;++i){
int x=to[read()],y=to[read()];
if(l[x]<=y&&y<=r[x])putchar('Y'),putchar('E'),putchar('S'),putchar('\n');
else putchar('N'),putchar('O'),putchar('\n');
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ5288 & 洛谷4436 & LOJ2508:[HNOI/AHOI2018]游戏——题解的更多相关文章
- BZOJ5290 & 洛谷4438:[HNOI/AHOI2018]道路——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5290 https://www.luogu.org/problemnew/show/P4438 的确 ...
- BZOJ5289 & 洛谷4437:[HNOI/AHOI2018]排列——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5289 https://www.luogu.org/problemnew/show/P4437 考虑 ...
- 【洛谷4424】[HNOI/AHOI2018] 寻宝游戏(位运算思维题)
点此看题面 大致题意: 给你\(n\)个\(m\)位二进制数.每组询问给你一个\(m\)位二进制数,要求你从\(0\)开始,依次对于这\(n\)个数进行\(and\)或\(or\)操作,问有多少种方案 ...
- 洛谷P4425 转盘 [HNOI/AHOI2018] 线段树+单调栈
正解:线段树+单调栈 解题报告: 传送门! 1551又是一道灵巧连题意都麻油看懂的题,,,,所以先解释一下题意好了,,,, 给定一个n元环 可以从0时刻开始从任一位置出发 每次可以选择向前走一步或者在 ...
- 洛谷P4426 毒瘤 [HNOI/AHOI2018] 虚树+树上dp
正解:虚树+树上dp 解题报告: 传送门! 首先解释一下题意趴,,,语文70pts选手已经开始看不懂题辣QAQ 大概就是个给一个图,求独立集方案,且保证图是联通的,边的数量最多只比点多10 首先思考如 ...
- 洛谷P4437 排列 [HNOI/AHOI2018] 贪心
正解:贪心 解题报告: 传送门! 发现做题龟速,,,所以懒得写题目大意辣自己get一下QAQ 首先看到ai<=n,又当ai=j时j在i的前面,所以就变成对于每个点i有一个约束,即要求第ai个节点 ...
- 洛谷P4438 道路 [HNOI/AHOI2018] 树形dp
正解:树形dp 解题报告: 传送门! 昂首先看懂题目趴QwQ大概就是说有棵满二叉树,有n个叶子节点(乡村)和n-1个非叶子节点,然后这棵树的每个节点有三个属性abc,对每个非叶子节点可以从与子节点的两 ...
- 【洛谷 P4437】 [HNOI/AHOI2018]排列(贪心,堆)
题目链接 如果\(j<=k,a_{p[j]}!=p[k]\)可以理解为如果\(a_{p[j]}=p[k]\),那么\(k\)一定要放在\(j\)前面,也就是\(a_j\)在\(j\)前面. 于是 ...
- 洛谷P1512伊甸园的日历游戏题解
题目 因为可能要参加qbxt的数论考试,所以最近要开始猛刷数论题了. 这是第一道,不过看样子并不想数论题啊,只是一个博弈论. 思路 一位著名老师说过,数学就是转化和化简,所以先考虑化简,先考虑化简年份 ...
随机推荐
- Linux 7.4配置VSFTP服务器
vsftpd(very secure ftp daemon,非常安全的FTP守护进程)是一款运行在Linux操作系统上的FTP服务程序,不仅完全开源而且免费,此外,还具有很高的安全性.传输速度,以及支 ...
- poj3984迷宫问题(dfs+stack)
迷宫问题 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 35426 Accepted: 20088 Descriptio ...
- beauifulsoup模块的介绍
01 爬虫基础知识介绍 相关库:1.requests,re 2.BeautifulSoup 3.hackhttp 使用requests发起get,post请求,获取状态码,内容: 使用re匹 ...
- js for循环实例
1.求1-100的寄数和? //2.奇数求和 var ppt=0 for(var i=1;i<=100;i+=2){ ppt+=i } 2.求1-100的偶数和 var num=0 for(va ...
- lintcode373 奇偶分割数组
奇偶分割数组 分割一个整数数组,使得奇数在前偶数在后. 您在真实的面试中是否遇到过这个题? Yes 样例 给定 [1, 2, 3, 4],返回 [1, 3, 2, 4]. 我的方法:设定两个数组,分别 ...
- css多行文本溢出显示省略号(…)
text-overflow:ellipsis属性可以实现单行文本的溢出显示省略号(…).但部分浏览器还需要加宽度width属性. css代码: overflow: hidden; text-overf ...
- [Clr via C#读书笔记]Cp2生成打包部署和管理应用程序和类型
Cp2生成打包部署和管理应用程序和类型 部署问题 DLL Hell;安装的复杂性:安全性:代码访问安全性. csc.exe的简单使用. 元数据 定义表:引用表:清单表: 程序集 重用,版本控制,安全的 ...
- 已有海外版Office365,如何开通相同Tenant的Azure
下面这个步骤是开通海外版Azure的测试账号,请了解! 翻到如图位置 点击免费开始 下一步 输入验证代码,此页没截图 使用信用卡,需要visa或master 下一步认证完就可以使用,没有继续截图
- 利用人脸特征提取DeepID--解读世纪晟人脸识别
概述:DeepID的目标是人脸验证(判断两张图片是否是一个人),同时衍生出人脸识别(多次人脸验证). DeepID采用增大数据集的方法: 增加新的数据,celebFaces(87628张图片,5436 ...
- 《剑指offer》---寻找反转数组最小值
本文算法使用python3实现 1.题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4, ...