知识点:约瑟夫环

2023大厂真题提交网址(含题解):

www.CodeFun2000.com(http://101.43.147.120/)

最近我们一直在将收集到的机试真题制作数据并搬运到自己的OJ上,供大家免费练习,体会真题难度。现在OJ已录入50+道2023年最新大厂真题,同时在不断的更新。同时,可以关注"塔子哥学算法"公众号获得每道题的题解。
在这里插入图片描述

问题形式:

n n n个人围成一圈,第一个人从1开始报数,报 m m m的将被杀掉,下一个人接着从1开始报。如此反复,最后剩下一个,求最后的胜利者。

思路:

1.暴力模拟: O ( n 2 ) O(n^2) O(n2).

2.高级数据结构解法: O ( n l o g n ) O(nlogn) O(nlogn)

做法:我们假设上一次被删除的位置是 p p p(初始 p = 1 p=1 p=1),且当前还有 c n t cnt cnt个数。那么下一个要删的位置 p ′ = ( p − 1 + k − 1 ) % c n t + 1 p'=(p-1+k-1)\%cnt+1 p=(p1+k1)%cnt+1.需要求区间前缀和(代表它在剩下位置中排第几).单点置0。显然利用线段树或者树状数组模拟这个过程即可.

3.递推解法: O ( n ) O(n) O(n)

注:这种方法只能求最后一个胜利者,而上面两个都可以求具体删除序列。

d p ( i ) dp(i) dp(i)为长度为 i i i的约瑟夫环,最后一个人的下标 i , i ∈ [ 0 , i ) i,i \in[0,i) i,i[0,i)

d p ( i ) = ( d p ( i − 1 ) + k )   %   i dp(i)=(dp(i-1)+k)\ \% \ i dp(i)=(dp(i1)+k) % i.

理解:参考博客

大致思路是:对于一个长度为 i i i的约瑟夫环,在删除完第一个数 k k k后。将它之前的数接在队尾。让 k + 1 k+1 k+1变成队头。那么现在的问题形式就变成了 d p ( i − 1 ) dp(i-1) dp(i1).区别在于下标不一样了。假设 d p ( n − 1 ) = m dp(n-1)=m dp(n1)=m.那么将其倒推成 n n n时,它的相对下标就得加上 k k k.即 d p ( i ) = ( d p ( i − 1 ) + k )   %   i dp(i)=(dp(i-1)+k)\ \% \ i dp(i)=(dp(i1)+k) % i.

拓展:

1. n n n很大, k k k相对较小的情况:题目链接

思路:观察递推式 d p ( i ) = ( d p ( i − 1 ) + k )   %   i dp(i)=(dp(i-1)+k)\ \% \ i dp(i)=(dp(i1)+k) % i。发现只有当 d p ( i − 1 ) + k ≥ i dp(i-1)+k \geq i dp(i1)+ki时, m o d    i mod \ \ i mod  i才起作用。所以列方程求最小的 t t t使得 d p + t k ≥ i + t dp+tk \geq i+t dp+tki+t.

t = ⌈ r − d p ( r ) k − 1 ⌉ t= \lceil \frac{r - dp(r)}{k-1} \rceil t=k1rdp(r)。不停这么做直到 r = = n r == n r==n

复杂度分析(太妙了): O ( k l o g n ) O(klogn) O(klogn).
在这里插入图片描述

2.求k次约瑟夫环变换后的序列. k ≤ 1 e 9 k \leq 1e9 k1e9. 题目链接

比如说进行一次(5,3)的约瑟夫环变换的访问序列是: 12345 − > 31524 12345->31524 12345>31524.

朴素解法复杂度 O ( k n 2 ) O(kn^2) O(kn2)

但是我们可以利用置换群快速幂这个算法来快速求解。那么首先先树状数组求出一次变换后的访问序列,然后再上快速幂即可。该算法待学习.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值