【口胡】Ynoi刷题记录

[Ynoi2019 模拟赛] Yuno loves sqrt technology III

分块后,预处理 F i , j F_{i,j} Fi,j表示第 i ∼ j i\sim j ij块的众数的出现次数。

用vector按顺序存每个数值所有元素的出现位置。

再记录每个元素在相应vector里的下标 p p p

考虑询问,中间的直接使用预处理出的 F i , j F_{i,j} Fi,j的值即可。设当前的答案 a n s = F i , j ans=F_{i,j} ans=Fi,j

考虑边界的元素。这里我们运用迭代的思想。对于右边的边角元素 x x x,如果它的出现次数比ans大,那么 p x − a n s p_x-ans pxans 的元素 y y y 当然大于等于 l l l 。这个判断是O(1)的。

显然,由于边界的数最多 2 n 2\sqrt n 2n 个,所以最多使得答案增加 2 n 2\sqrt n 2n

每次询问对 O ( n ) O(\sqrt n) O(n )个元素检查,++ans的次数为 O ( n ) O(\sqrt n) O(n )次。所以查询的时间复杂度为 O ( m n ) O(m\sqrt n) O(mn )

总时间复杂度 O ( ( n + m ) n ) O((n+m)\sqrt n) O((n+m)n ),空间复杂度 O ( n ) O(n) O(n)

[Ynoi2019 模拟赛] Yuno loves sqrt technology II

树状数组+莫队的时间复杂度是 O ( n l o g n m ) O(nlogn\sqrt{m}) O(nlognm )

考虑优化,我们发现我们的某一次询问其实是可以差分的。

即每次右指针右移的时候,都有这样的一组询问: l − r l-r lr中有多少数比 a r a_r ar

然而这个东西可以差分: [ 1 , r ] [1,r] [1,r]中比 a r a_r ar大的数的数量减去 [ 1 , l − 1 ] [1,l-1] [1,l1]中比 a r a_r ar大的数的数量。

对于前面那一坨可以用树状数组做。

后面那一坨询问离线下来处理即可。

这个时候我们一共存了 n m n\sqrt m nm 组移动(莫队复杂度,总移动次数)也就是要处理 n m n\sqrt m nm 组询问。

然而我们可以平衡它的复杂度,因为我们要处理 n m n\sqrt m nm 询问,却只需要插入 O ( n ) O(n) O(n)组数(即左端点扫过去的过程只移动 n n n 次)

可以使用一个插入 O ( n ) , O(\sqrt n), O(n ),查询 O ( 1 ) O(1) O(1)的数组结构 − > -> >值域分块。

对于莫队中的四种移动分 4 4 4类讨论,最后需要从 1 − n 1-n 1n用左端点扫一遍还需要再用右端点从 n − 1 n-1 n1扫一遍。

这样复杂度就被平衡到了 O ( n m + n n ) O(n\sqrt m+n\sqrt n) O(nm +nn )辣。

但是这样做要把 n m n\sqrt m nm 移动存下来,空间吃不下。

我们发现其实莫队的移动有规律,当右端点移动的时候,其左端点并没有发生任何移动,我们可以用 ( l , s t , e d , 1 / − 1 ) (l,st,ed,1/-1) (l,st,ed,1/1)来表示。

同理,当左端点移动的时候,右端点也没有发生任何移动。

这样空间复杂度就变成了 O ( M ) O(M) O(M)

本题的[st,ed]如果是 l l l的变化区间,就只把端点 s t st st, e d ed ed存进vector数组,当i=st时把询问加入,i=ed+1时把询问删除即可。操作总数仍然只有 O ( n m ) O(n\sqrt{m}) O(nm )次。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目 P5413 "YNOI2019 骑单车" 是一个经典的动态规划和贪心算法的问题。该题主要涉及两个概念:路径规划和状态转移方程。 **背景描述** 假设你在一个二维网格上,每个单元格代表一个地点,你需要从起点出发骑车到终点,并尽可能地减少骑行时间。网格中的每个单元格都有两种可能的状态:平地(速度不变)或斜坡(速度减半)。你的目标是找到一条最短的路线。 **关键点解析** 1. **动态规划**:通常用于求解最优化问题。在这个问题中,我们可以定义一个二维数组 dp[i][j] 表示从起点到位置 (i, j) 的最短行驶时间。状态转移方程会根据当前位置的性质(平地还是斜坡)以及到达此位置的最短路径来自之前的节点计算。 2. **状态转移**:对于平地,dp[i][j] = dp[pi][pj] + cost,表示直接移动到相邻位置的时间;对于斜坡,dp[i][j] = min(dp[pi][pj], dp[pi][pj-1]) + cost/2,因为斜坡速度减半,所以需要选择更早的时刻经过。 3. **贪心策略**:有时候,为了达到全局最优,初始看起来不是最优的选择可能是正确的。但在这个问题中,贪心策略可能并不适用,因为我们不能仅依据当前状态做出决策,需要考虑到整个路径。 4. **边界条件**:初始化 dp 数组时,起点时间设为 0,其余位置设为正无穷大,保证一开始就只会向可达的位置移动。 **代码实现** 实现这样的动态规划算法通常需要用到一个优先队列(如最小堆),以便于高效地查找之前节点的最优时间。 **相关问题--:** 1. 如何设计状态转移方程来处理平地和斜坡的情况? 2. 这个问题是否存在剪枝操作以提高效率? 3. 如果网格大小非常大,如何避免存储所有 dp 值导致的空间爆炸?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值