当前位置: 首页 > news >正文

递推预处理floor(log_2{n})

在C++中,除了使用<cmath>中的loglog2函数求对数,也可以通过递推求出所有可能用到的⌊log⁡2i⌋,i∈[1,n]\lfloor \log_2i\rfloor, i\in[1, n]log2i,i[1,n]

证明:⌊log⁡2i⌋=⌊log⁡2⌊i2⌋⌋+1\lfloor \log_2i \rfloor=\lfloor \log_2 \lfloor \frac{i}{2} \rfloor \rfloor+1log2i=log22i⌋⌋+1
由于log⁡2i=log⁡2(i2⋅2)=log⁡2i2+log⁡22=log⁡2i2+1\log_2i=\log_2(\frac{i}{2}\cdot 2)=\log_2\frac{i}{2}+\log_22=\log_2\frac{i}{2}+1log2i=log2(2i2)=log22i+log22=log22i+1
等号两边都向下取整,得:
⌊log⁡2i⌋=⌊log⁡2i2⌋+1\lfloor \log_2i \rfloor =\lfloor \log_2\frac{i}{2} \rfloor+1log2i=log22i+1

  • 如果iii是偶数,则i2=⌊i2⌋\frac{i}{2}=\lfloor \frac{i}{2} \rfloor2i=2i,因此有
    ⌊log⁡2i⌋=⌊log⁡2i2⌋+1=⌊log⁡2⌊i2⌋⌋+1\lfloor \log_2i \rfloor =\lfloor \log_2\frac{i}{2} \rfloor+1 = \lfloor \log_2\lfloor \frac{i}{2} \rfloor \rfloor+1log2i=log22i+1=log22i⌋⌋+1
  • 如果iii是奇数,则i−12=⌊i2⌋\frac{i-1}{2}=\lfloor \frac{i}{2} \rfloor2i1=2i
    ⌊log⁡2i−12⌋=x\lfloor \log_2\frac{i-1}{2} \rfloor =xlog22i1=x
    那么x≤log⁡2i−12<x+1x\le \log_2\frac{i-1}{2}<x+1xlog22i1<x+1
    2x≤i−12<2x+12^x\le \frac{i-1}{2}<2^{x+1}2x2i1<2x+1
    由于i−12\frac{i-1}{2}2i1是整数,2x+12^{x+1}2x+1也是整数,较小的整数加上12\frac{1}{2}21后,一定小于较大的整数。
    因此有2x≤i−12<i−12+12=i2<2x+12^x\le \frac{i-1}{2}<\frac{i-1}{2}+\frac{1}{2}=\frac{i}{2}<2^{x+1}2x2i1<2i1+21=2i<2x+1
    所以x≤log⁡2i2<x+1x\le \log_2{\frac{i}{2}}<x+1xlog22i<x+1
    因此⌊log⁡2i2⌋=x=⌊log⁡2i−12⌋=⌊log⁡2⌊i2⌋⌋\lfloor \log_2{\frac{i}{2}} \rfloor =x= \lfloor \log_2\frac{i-1}{2} \rfloor= \lfloor \log_2\lfloor \frac{i}{2}\rfloor \rfloorlog22i=x=log22i1=log22i⌋⌋
    因此⌊log⁡2i⌋=⌊log⁡2i2⌋+1=⌊log⁡2⌊i2⌋⌋+1\lfloor \log_2i \rfloor =\lfloor \log_2\frac{i}{2} \rfloor+1 = \lfloor \log_2\lfloor \frac{i}{2} \rfloor \rfloor+1log2i=log22i+1=log22i⌋⌋+1
    证毕。

已知⌊log⁡21⌋=0\lfloor \log_21 \rfloor=0log21=0,结合递推式⌊log⁡2i⌋=⌊log⁡2⌊i2⌋⌋+1\lfloor \log_2i \rfloor=\lfloor \log_2 \lfloor \frac{i}{2} \rfloor \rfloor+1log2i=log22i⌋⌋+1即可递推得到所有可能用到的⌊log⁡2i⌋,i∈[1,n]\lfloor \log_2i\rfloor, i\in[1, n]log2i,i[1,n]

代码如下:

const int N = 1000005;//N设为n可能达到的最大值
int lg[N];//lg[i]:floor(log_2{i})
void initLg(int n)//生成lg[1]~lg[n]
{//全局变量初值为0,已经设好lg[1] = 0for(int i = 2; i <= n; ++i)lg[i] = lg[i/2]+1;
}

预处理lg数组的时间复杂度为O(n)O(n)O(n)

http://www.dtcms.com/a/279853.html

相关文章:

  • Class9简洁实现
  • HashMap的put过程以及hashMap的简单介绍
  • kt 中商品的金额字段使用double 还是 bigdecimal
  • 动态规划题解——最长递增子序列【LeetCode】记忆化搜索方法
  • 【每日刷题】杨辉三角
  • Git根据标签Tag强制回滚版本
  • 面试常问:如何在一个长度为n的无序数据快速获取前k个数值
  • 网络传输过程
  • GaussDB between的用法
  • 光伏板如何最大化铺设?
  • 【PostgreSQL异常解决】`PostgreSQL`异常之类型转换错误
  • 记录自己在将python文件变成可访问库文件是碰到的问题
  • vert.x 官网docs, vert.x中文文档地址 vertx文档
  • 文心4.5开源之路:引领技术开放新时代!
  • 【前端:Typst】--let关键字的用法
  • 高德开放平台携手阿里云,面向开发者推出地图服务产品MCP Server
  • 外部协作不力影响项目进度,如何加强外部沟通
  • 项目进度压缩影响质量,如何平衡进度与质量
  • LeetCode|Day11|557. 反转字符串中的单词 III|Python刷题笔记
  • 稀土化合物:助力高效种植与健康养殖
  • vue笔记3 VueRouter VueX详细讲解
  • 对象的使用
  • CAN终端电阻为什么是60R+60R,而不直接用120R?
  • 前端vue对接海康摄像头流程
  • Flink窗口处理函数
  • C++-linux 5.gdb调试工具
  • 【从语言幻觉看趋势】从语言幻觉到多智能体协作:GPT多角色系统的技术演进与实践路径
  • 判断端口处于监听状态的方法
  • 腾讯云WAF域名分级防护实战笔记
  • EPLAN 电气制图(八):宏应用与变频器控制回路绘制全攻略