26.1.24 分块|排序|中位数贪心+线段树二分+聚集贪心

E. GukiZ and GukiZiana

分块

整体加,还要维护一个值的最早出现,这无法线段树。

考虑分块。每个块内维护哈希表,记录块内每个值的最早和最晚出现下标。更新时,整块值增加懒标记,非完整块,下放懒标记,单点加。然后重构这个块的哈希表。查询时,检查每个块哈希表内是否有查询元素,如果有,查哈希表得到具体下标。

这个做法维护两个哈希表,且是两个 m a p map map,常数有点大,理论上能过但是会被卡常。

考虑一个更自然的想法,我们如果定位到一个块内有我们要找的元素,直接去线性地扫一遍这个块不就好了?这只有 O ( n ) O(\sqrt n) O(n )地开销,但是避免维护两个保存下标的哈希表,只用一个 u s e t uset uset维护块内出现的元素即可。这样代码也更好写。并且,这样的话,更新和查询的工作量也更平衡,不用费劲调块长也能过(前一个做法查询的工作量很小,更新的工作量很大)

E. Anya and Cubes

折半搜索

每个元素有:不选,选中但不阶乘,选中且阶乘,三种选择。

直接爆搜 3 25 3^{25} 325太慢,但 3 12 3^{12} 312是可以接受的,考虑折半搜索,两次搜索分别搜前一半,后一半元素,得到方案数分别存在两组哈希表内,注意哈希表还需要保存方案使得几个数成为阶乘。然后枚举一边的哈希表,枚举有几个阶乘,枚举元素和,假设有 i i i个,元素和 s u m sum sum,那么另一边阶乘数不超过 k − i k-i k−i,元素和 s − s u m s-sum s−sum的方案都可以和当前方案组成合法方案,计入答案。

当然也可以搜前一半,保存在哈希表,然后搜另一半,搜到一个边界,就直接去查前一半的哈希表。

B. Stay or Mirror

排序 逆序对

一个排列,每个元素都可以保持不变,或和 n n n对称。问最小逆序对个数。

一个元素变或不变,需要考虑左侧比他大的元素,和右侧比它小的元素,有点复杂。这种要考虑太多的问题,不妨找到一个边界,使我们只需要考虑一边

比如考虑 1 1 1这个元素。如果它不变,其他元素不论变或不变,都会比他大,如果它变了,其他元素不论变或不变,都会比他小。那么尽管其他元素还未确定,变或不变时,涉及 1 1 1的逆序对都是可以计算的,我们比较这两种情况,哪个的逆序对个数更少,就能决定 1 1 1应该选哪个。

那么这样的话, 1 1 1确定了,看 2 2 2,比 2 2 2大的元素未确定,但可以利用和上面类似的思路确定产生的逆序对,比 2 2 2小的元素 1 1 1已经确定了,可可以确定 2 , 2 n − 2 2,2n-2 2,2n−2和 1 1 1形成的逆序对,所以 2 2 2变不变,的逆序对也可以计算出来,然后决定 2 2 2变不变。

到这里我们就可以发现了,如果我们从小到大确定元素的取值,比 i i i小的元素已经确定,和 i i i产生的逆序对当然是确定的,比 i i i大的元素,虽然不确定,但是和 i i i产生的逆序对仍然是确定的。于是我们就可以决定 i i i变或不变。

这种在两侧都有元素,不好确定时,利用排序,从一个边界出发递推的思想,很重要,边界往往只用考虑一边。

数据允许 O ( n 2 ) O(n^2) O(n2),可以对每个 i i i,扫描其他元素,计算边和不变产生的逆序对。

F. Putting Boxes Together

中位数贪心 线段树二分 聚集贪心

多个典缝合在一起。

只能 − 1 / + 1 -1/+1 −1/+1,把一个升序数组变成连续的, i , i + 1 , i + 2 i,i+1,i+2 i,i+1,i+2的操作次数,等价于把初始元素先变成 a i − i a_i-i ai−i,然后把元素变成全都相同。所以开始先把元素这样处理

接下来,把元素变成完全相同的最小操作次数,这是经典的中位数贪心。最小的方案是,把所有元素变成中位数。

但本题的特殊点在于,第 a i a_i ai想要移动 1 1 1,需要消耗 w i w_i wi的次数,而不是 1 1 1。也就是这是一个带权的中位数贪心。仍然可以类似的思想,只不过我们现在要找到的是带权中位数,对于一个序列 w 1 , w 2 . . w n w_1,w_2..w_n w1,w2..wn来说,就是要找到最小的 i i i, w 1 + . . + w i > = ( ∑ w ) / 2 w_1+..+w_i>=(\sum w)/2 w1+..+wi>=(∑w)/2, w i w_i wi都是正数,这可以二分来做。

找到 i i i之后,就是所有 j < i j<i j<i,代价都是 w j ∗ ( a i − a j ) w_j*(a_i-a_j) wj∗(ai−aj), j > i j>i j>i,代价都是 w j ∗ ( a j − a i ) w_j*(a_j-a_i) wj∗(aj−ai),要快速求和,则是 a i ∑ w j − ∑ ( w j a j ) , ∑ ( w j a j ) − a i ∑ w j a_i\sum w_j-\sum(w_ja_j),\sum(w_ja_j)-a_i\sum w_j ai∑wj−∑(wjaj),∑(wjaj)−ai∑wj,这可以线段树分别维护 ∑ w i \sum w_i ∑wi, ∑ w i ∗ a i \sum w_i*a_i ∑wi∗ai实现。

接下来的问题就是如何在带修的情况下快速找到中位数的位置 i i i,这可以线段树二分,二分条件已经分析了,很简单,找到最小的 i i i,满足 w l + . . + w i > = ( w l + . . + w r ) / 2 w_l+..+w_i>=(w_l+..+w_r)/2 wl+..+wi>=(wl+..+wr)/2,让线段树二分过程中,引用参数传递区间的前缀和

相关推荐
Anastasiozzzz2 小时前
Redis脑裂问题--面试坑点【Redis的大脑裂开?】
java·数据库·redis·缓存·面试·职场和发展
木土雨成小小测试员2 小时前
Python测试开发之后端一
开发语言·数据库·人工智能·python·django·sqlite
罗汉松驻扎的工作基地2 小时前
sql server开启远程(适用于2014、2017和2008R2)
运维·服务器·数据库
曹轲恒2 小时前
Redis入门(1)
数据库·redis·缓存
myloveasuka2 小时前
汉明编码的最小距离、汉明距离
服务器·数据库·笔记·算法·计算机组成原理
Elastic 中国社区官方博客2 小时前
Elasticsearch:使用 `best_compression` 提升搜索性能
大数据·运维·数据库·elasticsearch·搜索引擎·全文检索
羱滒2 小时前
Docker Compose + Nginx + 后端服务运行环境搭建全流程指南(redis、mongdb、nginx、nacos-registry)
redis·nginx·docker·docker-compose
先跑起来再说2 小时前
Redis Stream 深入理解:它到底解决了什么问题
数据库·redis·缓存