Description

传送门

Solution

注意到,原问题等价于加边,查询是否存在一个包含前 k k k 个点至少一者(令其为关键点)的环,并强制在线。

算法一

令 L u L_u Lu​ 表示节点 u u u 可达的编号最大的关键点, R u R_u Ru​ 表示可达节点 u u u 的编号最小的关键点。那么,答案为 1 1 1 当且仅当存在 u u u 使 L u ≥ R u L_u \ge R_u Lu​≥Ru​。

每当加入一条边 ( u , v ) (u,v) (u,v) 后,我们从 u u u 出发往外 dfs,不断尝试用 R u R_u Ru​ 来更新其他的 R R R;同理,我们也从 v v v 在反图上往外 dfs,不断尝试用 L v L_v Lv​ 来更新其他的 L L L。

一般实现的复杂度是 O ( m ( n + m ) ) O(m(n+m)) O(m(n+m)) 的,但如果我们加一个剪枝:无法更新就返回,那么每走一条边就会使一个节点的 L , R L,R L,R 之一产生变化。而根据势能分析,每个节点的 L , R L,R L,R 的变化次数总和是 O ( n k ) O(nk) O(nk) 的,所以总复杂度其实是 O ( ( n + m ) k ) O((n+m)k) O((n+m)k) 的。

期望得分 60 60 60 分。

算法二

既然关键点数量不多时算法一优秀,那么我们考虑将关键点变少。具体来说,我们分块,对于每个节点 u u u 维护 L u , R u L_u,R_u Lu​,Ru​ 所在的块。当块长为 k \sqrt k k ​ 时,复杂度就是 O ( ( n + m ) k ) O((n+m) \sqrt k) O((n+m)k ​) 的。

特别的,若 L u , R u L_u,R_u Lu​,Ru​ 属于同一个块,那么暴力更新。由于块长不大,所以这一部分的复杂度也是 O ( ( n + m ) k ) O((n+m) \sqrt k) O((n+m)k ​) 的。

总时间复杂度 O ( ( n + m ) k ) O((n+m) \sqrt k) O((n+m)k ​),期望得分 [ 60 , 100 ] [60,100] [60,100] 分。

算法三

首先你要注意到,分块本质上就是线段树的退化版,将线段树的层数压缩到了 2 2 2。然而,本题并不需要依赖分块的特殊结构,于是我们考虑转而用线段树来维护。

具体来说,以 [ − 1 , k ] [-1,k] [−1,k] 为值域建立线段树,将每个点 u u u 记录在极小的包含 [ L u , R u ] [L_u,R_u] [Lu​,Ru​] 的线段树节点处。我们不断地尝试用下层更新上层的点,使各个节点被记录的位置不断变深。在实现方面,我们并不需要建立线段树,只需对各个 u u u 维护其在虚拟的线段树上对应的区间即可。

由于线段树只有 O ( log ⁡ k ) O(\log k) O(logk) 层,所以总复杂度 O ( ( n + m ) log ⁡ k ) O((n+m) \log k) O((n+m)logk),完美解决本题。

Summary

看到本题,非常容易想到维护 L , R L,R L,R。

首先考虑 60 60 60 分怎么做,根据势能分析,发现 dfs 一下的复杂度就是对的。

再考虑 100 100 100 分怎么做。由于关键点的数量较少可以做,那么我们可以分块,这样就能做到较为优秀的 O ( ( n + m ) k ) O((n+m) \sqrt k) O((n+m)k ​)。

最后发现做法并不依赖分块结构的特殊性,于是转而用线段树大力维护,就能做到完美的 O ( ( n + m ) log ⁡ k ) O((n+m) \log k) O((n+m)logk) 了。

本题关键在于挖掘出转移的特殊性,并考察了对分块,分治等结构的清楚认识,是一道不可多得的好题。

Code

略微压行,代码很短,只有 663 B。

#include <bits/stdc++.h>
using namespace std;
const int N=3e5+5;int n,k,l[N],r[N]; vector<int> A[N],B[N];
void init(int _n,int _k){n=_n,k=_k;for (int i=0;i<k;i++)  l[i]=r[i]=i;for (int i=k;i<n;i++)  l[i]=-1,r[i]=k;
}
bool upd(int u);
bool chk(int u,int v){if (l[u]>=r[v])  return 1;int midu=(l[u]+r[u])>>1,midv=(l[v]+r[v])>>1;if (l[u]>midv)  return l[v]=midv+1,upd(v);if (r[v]<=midu)  return r[u]=midu,upd(u);return 0;
}
bool upd(int u){for (auto v:A[u]) {if(chk(u,v))return 1;}for (auto v:B[u]) {if(chk(v,u))return 1;}return 0;
}
int add_teleporter(int u,int v){A[u].push_back(v),B[v].push_back(u);return chk(u,v);}

[APIO2022] 游戏 题解相关推荐

  1. 阿狸和桃子的游戏题解

    阿狸和桃子的游戏题解 每一道代码简单的黑题都有着诡异的思想,真不知道出题者怎么想的. 而这道题的重点在于把边权转换为点权, 此题的方式是将边权w平均分给被连接的两点u和v. 若u和v都被一人选择,则他 ...

  2. 洛谷P1129 [ZJOI2007] 矩阵游戏 题解

    洛谷P1129 [ZJOI2007] 矩阵游戏 题解 题目链接:P1129 [ZJOI2007] 矩阵游戏 题意:给定一张有黑白棋子的正方形棋盘,问存不存在解法使得经过若干次交换行或列的操作后,左上角 ...

  3. P1199(NOIP2010 普及组)三国游戏 题解

    P1199(NOIP2010 普及组)三国游戏题解 Step-1 输入(重点) 输入n:int n;cin>>n; 输入数组: int a[1001][1001]; for(int i=1 ...

  4. NOIp2012D1T2 国王游戏 题解

    国王游戏 洛谷P1080国王游戏 题解 这道题有个重要的性质:如果交换相邻两个大臣,获得金钱变化的有且只有这两个大臣.其余大臣得到的金钱不变. 我们考虑第 i i i个大臣和第 i + 1 i+1 i ...

  5. 随缘学习 扫雷游戏 题解

    随缘学习 扫雷游戏 题解 作者名:nlc3030 学习目的:随缘学习,熟练下java的使用 题解: 01 这个扫雷游戏,通过题目知道就是定义一个二维数组,然后进行逐个查找进行扫雷 02 在写代码的时候 ...

  6. P1057传球游戏 题解

    P1057传球游戏 题解 题目描述: 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:nnn个同学站成一个圆圈,其中的一个同学手里拿着一个球 ...

  7. P2356 弹珠游戏题解

    P2356 弹珠游戏题解 先说都会的TIE两个点的题解- #include<bits/stdc++.h> using namespace std; int n; int a[10001][ ...

  8. Bzoj 2563: 阿狸和桃子的游戏 题解

    2563: 阿狸和桃子的游戏 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: 970  Solved: 695 [Submit][Status][Dis ...

  9. [NOIP2010 普及组] 三国游戏 题解

    一只蒟蒻,第一次写题解,有错误还望指正! [NOIP2010 普及组] 三国游戏 题目https://www.luogu.com.cn/problem/P1199 题意理解 废话不多说,我们先看题目. ...

最新文章

  1. 2022-2028年中国文化产业园投资分析及前景预测报告(全卷)
  2. TensorFlow快餐教程:程序员快速入门深度学习五步法
  3. sigprocmask和sigsuspend转
  4. ARC 没有自动释放内存
  5. VTK:Utilities之SortDataArray
  6. C++ template类模板实现栈 pop push
  7. JDBC学习笔记 day1
  8. 为什么你应该用Yarn而不是Npm来管理你的项目依赖?
  9. mongodb 启动脚本和配置
  10. hibernate注释映射_Hibernate一对多映射示例注释
  11. java 100个定时任务_Java定时任务解决方案
  12. WordPress SEO 完全指南
  13. 计算机键盘上删除,电脑键盘删除键是哪一个
  14. 如果你的下属不服从你得管理,你会怎么办?
  15. python画江苏_江苏高考数学再现算法流程图!学过编程的孩子都说So easy!
  16. excel如何转化成word文件
  17. 《阿丽塔:战斗天使》:人类与机器人真的有爱情吗?
  18. 2022年国家法定节假日放假时间安排
  19. WKWebView预初始化
  20. 回到1996,一起领略 JavaBeans 的真正力量

热门文章

  1. 微信 请求校验(确认请求来自微信服务器)
  2. 企业为什么要选择软文营销?
  3. Java Concurrency In Practice
  4. 一份详细的Google hacking语法(Google搜索语法)
  5. Python中的strip().split(‘\t‘)的用法和解释
  6. 辉太郎看前端(查找出字符串或数组中出现次数最多的字符)
  7. w3c标准html,W3C标准及规范
  8. 计算机系统硬盘拷贝,不用互助,轻松搞定新旧电脑间系统完整复制或硬盘更换!...
  9. 打印公司员工信息表java,打印模板 java
  10. Codeforces1442 D. Sum(dp+分治优化)