| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 【牛客多校 2021 第10场 E】More Fantastic Chess Problem (分析与数据结构) -> 正文阅读 |
|
[数据结构与算法]【牛客多校 2021 第10场 E】More Fantastic Chess Problem (分析与数据结构) |
【题目链接】【题意】? 定义 k k k 维度国际象棋是一个在 a 1 × a 2 × ? × a k a_1\times a_2\times \dots \times a_k a1?×a2?×?×ak? 的棋盘上进行的游戏,其中规定棋盘的对角位置分别为 ( 1 , 1 , … , 1 ) (1,1,\dots ,1) (1,1,…,1) 和 ( a 1 , a 2 , … , a k ) (a_1,a_2,\dots ,a_k) (a1?,a2?,…,ak?) 。 ? 定义国际象棋中的棋子 King?(国王)?,?Queen?(王后)?,?Rook?(车)?,?Bishop?(象)?,?Knight?(马)? \text{King (国王) , Queen (王后) , Rook (车) , Bishop (象) , Knight (马) } King?(国王)?,?Queen?(王后)?,?Rook?(车)?,?Bishop?(象)?,?Knight?(马)? 的走法如下:
? 现在棋盘上只有一颗棋子,给出这个棋子的类型和初始位置 ( b 1 , b 2 , … b k ) (b_1,b_2,\dots b_k) (b1?,b2?,…bk?) ,询问其一次行动后能到达的位置一共有多少个。接下来棋子还有 q q q 次移动,每次移动会变化 d d d 个维度,每个维度的变化会用 ( x , δ ) (x,\delta) (x,δ) 的形式给出,表示这次移动将 x x x 维度上的位置变化了 δ \delta δ 。保证每次移动是棋子的合法走法。每次移动后你仍然需要输出棋子在当前位置上,一次行动后能到达的位置一共有多少个。答案对大质数取模。 【数据范围】? k , q ≤ 3 × 1 0 5 , ?? ∑ d ≤ 3 × 1 0 5 , ?? a i ≤ 1 0 6 k,q\le 3\times 10^5,\ \ \sum d \le 3\times 10^5 ,\ \ a_i \le 10^6 k,q≤3×105,??∑d≤3×105,??ai?≤106 【思路】? 本题是一道分析好题,其实现算法不难,在比赛中,其本身具有一定的分析深度。 ? 我们按照不同的棋子,给出其走法方案数的分析,以及维护方法。 ? 注意一点,在维护棋子的移动中,移动的维度的总数量是同 O ( k ) O(k) O(k) 的,所以我们只需要思考某个维度移动之后如何维护答案即可。 【 King \text{King} King】? 我们发现各个维度之间的走法互不干扰,都有 + 1 , 0 , ? 1 +1,0,-1 +1,0,?1 三种选择,于是通常情况下有 3 k 3^k 3k 种走法,减去不动的一种走法是 3 k ? 1 3^k-1 3k?1 种。但是有的时候,当我们处于边界了,有些走法就不能被采用了。如果第 i i i 个维度的位置 b i = 1 b_i=1 bi?=1 ,则不能再 ? 1 -1 ?1 ,如果 b i = a i b_i=a_i bi?=ai? 则不能再 + 1 +1 +1 。 ? 于是我们可以维护一下,当前位置下,能有两种选择的维度的数量 c 2 c_2 c2? ,和能有三种选择的维度的数量 c 3 c_3 c3? ,那么当前的合法走法就有 2 c 2 × 3 c 3 ? 1 2^{c_2}\times 3^{c_3} - 1 2c2?×3c3??1 种。 ? 当某个维度发生移动时,我们先删掉它,根据他当前的位置更新 c 2 , c 3 c_2,c_3 c2?,c3? 的值,然后改变他的位置,再根据他新的位置更新 c 2 , c 3 c_2,c_3 c2?,c3? 的值即可。每次移动可以 O ( 1 ) O(1) O(1) 维护,每次询问时可以写个快速幂构造答案,总复杂度 O ( k log ? k ) O(k\log k) O(klogk) 。
【 Queen \text{Queen} Queen】? 我们发现 Queen \text{Queen} Queen 和 King \text{King} King 的走法几乎一致,只是需要对移动距离 x ∈ [ 1 , n ] x\in[1,n] x∈[1,n] 全部做考虑。于是我们对每个移动距离 x x x 都维护一下 2 c x 2 × 3 c x 3 2^{c_{x2}}\times 3^{c_{x3}} 2cx2?×3cx3? 的值,那么答案就是 ( ∑ x = 1 v 2 c x 2 × 3 c x 3 ) ? v (\sum_{x=1}^v 2^{c_{x2}}\times 3^{c_{x3}})- v (∑x=1v?2cx2?×3cx3?)?v ,其中 v = 1 0 6 v=10^6 v=106 。 ? 当某个维度发生移动时,我们先删掉它: ? 根据他当前的位置 b i b_i bi? ,我们令 u = a i ? b i , v = b i ? 1 u=a_i - b_i,v=b_i-1 u=ai??bi?,v=bi??1 ,对于 x > max ? ( u , v ) x>\max(u,v) x>max(u,v) 的移动距离,其贡献不受影响;对于 x ≤ min ? ( u , v ) x\le \min(u,v) x≤min(u,v) 的移动距离,都少掉了一个 3 3 3 选择的维度,因此把他们都除以 3 3 3 ;对于 min ? ( u , v ) < x ≤ max ? ( u , v ) \min(u,v) <x\le \max(u,v) min(u,v)<x≤max(u,v) 的移动距离,都少掉了一个 2 2 2 选择的维度,因此把他们都除以 2 2 2 。也就是说,对移动距离分三个区间,对其中两个做区间除法(乘法,乘以逆元)。 ? 然后我们改变这个维度,再考虑加入它: ? 根据他新的位置 b i b_i bi? ,我们令 u = a i ? b i , v = b i ? 1 u=a_i - b_i,v=b_i-1 u=ai??bi?,v=bi??1 ,和上面同理,正好相反,对于 x ≤ min ? ( u , v ) x\le \min(u,v) x≤min(u,v) 的移动距离,把他们的贡献都乘以 3 3 3 ;对于 min ? ( u , v ) < x ≤ max ? ( u , v ) \min(u,v) <x\le \max(u,v) min(u,v)<x≤max(u,v) 的移动距离,把他们都乘以 2 2 2 。也是用两个区间乘法维护。 ? 于是可以用一个初始化每个位置都为
1
1
1 的线段树,维护区间乘法和
【 Rook \text{Rook} Rook】? 唯一没用的棋子,无论走到哪里,下一步始终都有 ( ∑ i = 1 k a i ) ? k (\sum_{i=1}^{k} a_i)-k (∑i=1k?ai?)?k 种走法。 ? 于是直接输出 q q q 次答案就可以了,总复杂度 O ( q ) O(q) O(q) 。
【 Bishop \text{Bishop} Bishop】? 之前的维护给了我们一个类似于差分的启示:只要我们能够动态维护一个维度出现/消失带来的贡献变化,我们就可以动态维护答案。 ? 所以同理,我们可以这样来思考 Bishop \text{Bishop} Bishop 。 ? 该棋子有这个特点,如果棋子移动的两个维度以及其方向都选定了,那么走法是两个方向上能走的最大距离中较小的那一个。 ? 如果加入一个维度,根据棋子目前的位置,这个维度在正方向上最多可以走 u u u 的距离,在负方向上最多可以走 v v v 的距离,那么这个维度会带来多少贡献呢?选中这个维度后,在这个维度上的走法无非就是 u + v u+v u+v 种,如果选走正方向: ? 那么考虑其他所有维度的所有方向:如果其能走的长度 x ≤ v x\le v x≤v ,那么能带来 x x x 的贡献,如果 x ≥ v x\ge v x≥v 那么就能带来 v v v 的贡献。 所以只需要统计其他方向距边界距离小于等于 v v v 的这些距离的总和,以及距边界距离大于 v v v 的方向个数 × v \times v ×v 的值即可。 ? 如果选走负方向,把 v v v 换成 u u u ,计算方式完全一致。 ? 同样,如果是删除一个维度,计算其失去的贡献也是一样的。 ? 可以发现,要这样计算贡献,需要对现有的方向的距边界距离做一个权值上的维护,支持单点修改和区间查询。 ? 于是可以用两个权值树状数组,一个维护权值的数量,一个维护权值的和。总复杂度 O ( k log ? v ) O(k\log v) O(klogv) 。
【 Knight \text{Knight} Knight】? 同上,我们发现 Knight \text{Knight} Knight 的移动也是选中两个维度,但是其在一个维度上走的方式很有限,可以类似 Bishop \text{Bishop} Bishop 的方式来维护加入一个维度和删除一个维度带来的贡献变化,同时维护现有方向的各种走法的数量。 ? 该棋子的特点是,如果棋子移动的两个维度以及其方向都选定了,一个维度走 1 1 1 的距离,另一个维度走 2 2 2 步。 ? 我们直接用两个变量,分别维护当前考虑的维度中,有 c 1 c_1 c1? 个方向可以走 1 1 1 的距离,有 c 2 c_2 c2? 个方向可以走 2 2 2 的距离。 ? 如果加入一个维度,根据棋子目前的位置,这个维度在正方向上最多可以走 u u u 的距离,在负方向上最多可以走 v v v 的距离。根据 u , v u,v u,v 和 1 , 2 1,2 1,2 的大小关系,就可以维护其带来的贡献。 ? 删除一个维度同理。维护是 O ( 1 ) O(1) O(1) 的。 ? 总复杂度 O ( k ) O(k) O(k) 。
【其余部分的代码】 (树状数组、线段树、主函数,拼上上面那几个结构体就可以跑了)
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 23:00:11- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |