浅谈倍增及应用

article/2025/9/29 16:08:34

浅谈倍增

倍增思想

原理:

倍增,即成倍增长。在处理一系列序列数据时,倍增可通过指数级的增长快速覆盖所有数据。

倍增算法采用2倍增长的方式,其核心思想是建立以下数组T a[i][j] ,表示自i向后共 2 j 2^j 2j个数据的某些特性,如最大值等

倍增算法的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),其中倍增的初始化为 O ( n l o g n ) O(nlogn) O(nlogn),查询 O ( 1 ) O(1) O(1)

实现:

首先,我们需要初始化 l o g 2 log_2 log2数组,以便查询

log[1] = 0;
for(int i = 2; i <= N; i++)log[i] = log[i/2] + 1;

而后,我们对倍增数组进行初始化,这里倍增数组表示最大值

for(int i = 1; i <= N; i++){cin >> a[i][0];
}
for(int i = 0; i <= N; i++){for(int j = 1; i + (1<<j) - 1 <= N; j++){a[i][j] = max(a[i][j-1],a[i+(1<<(j-1))][j-1]);}
}

最后,我们来实现查询操作

int l,r;
cin >> l >> r;
int k = log[r-l+1];
int ans = max(a[l][k],a[r-(1<<k)+1][k]);

应用

倍增作为一种程序设计的基本思想,广泛应用于各种算法中,其中最常见的用途有三种:快速幂、RMQ、LCA

快速幂

对于要计算的 a k a^k ak,可对 k k k进行二进制分解,当 k k k最后一位为1时,易知, a n s = a ∗ a k − 1 ans = a * a^{k-1} ans=aak1,此时我们可以令 a n s ∗ = a ans*=a ans=a,再使得原来的 a k a^k ak变成 a k − 1 a^{k-1} ak1,其中, a k − 1 = ( a 2 ) k > > 1 a^{k-1} = (a^2)^{k>>1} ak1=(a2)k>>1,则只需令 a = a ∗ a a = a * a a=aa,再令$ k = k>>1$

而当 k k k的最后一位不为1时,可知, a k = ( a 2 ) k > > 1 a^k = (a^2)^{k>>1} ak=(a2)k>>1,只需令 a = a ∗ a a = a * a a=aa,再令$ k = k>>1$

int qpow(int a,int k){int ans = 1;while(k){if(k&1)ans*=a;k>>1;a*=a;}
}

RMQ

R M Q RMQ RMQ R a n g e M a x i m u m ( M i n i n u m ) Q u e r y Range \ Maximum(Mininum)\ Query Range Maximum(Mininum) Query的缩写,即区间最大/小值的查询问题

最大值查询实现如下:

log[0]=1;
for(int i=1;i<=n;i++)log[i]=log[i/2]+1;
for(int i=1;i<=n;i++)cin>>a[i][0];
for(int i=1;i<=n;i++){for(int j=1;i+(1<<j)-1<=n;j++)a[i][j]=max(a[i-1][j-1],a[i+(1<<(j-1))][j-1]);
}
int k=log[r-l+1];
int ans=max(a[l][k],a[r-(1<<k)+1][k]);

LCA

L C A LCA LCA L e a s t C o m m o n A n c e s t o r s Least\ Common\ Ancestors Least Common Ancestors的缩写,即最近公共祖先问题,是树论中的经典问题

截屏2022-10-20 10.40.03

如上图, L C A ( 5 , 9 ) = 2 LCA(5,9) = 2 LCA(5,9)=2

利用倍增思想,我们可以预处理出每个节点的 2 k 2^k 2k级祖先,之后开始操作:

对于两个深度不同的节点,先让深度低的节点向上跳,直到处于相同深度

int lca(int x,int y){if(depth[x]<depth[y]) swap(x,y);while(depth[x]>depth[y]) x=st[x][log[depth[x]-depth[y]]]; if(x==y) return y;for(int k=log[depth[x]];k>=0;k--) if(st[x][k]!=st[y][k]){x=st[x][k];y=st[y][k];}return st[x][0];
}

总结

倍增算法的精髓,是对大范围数据采用指数级的处理,通过指数次数的减少再来提高精确度,即二进制分解,再逐步对每一位进行操作。如,在 L C A LCA LCA中,采用将向上跳的数量通过二进制分解;在快速幂中,对幂数进行二进制分解,从而降低复杂度

倍增算法不仅仅用于这三种算法,其思想需融会贯通于程序设计中,以提高程序效率


http://chatgpt.dhexx.cn/article/J3wCahPe.shtml

相关文章

倍增(ST表与LCA)

倍增&#xff08;ST表与LCA&#xff09; 什么是倍增&#xff1f; 倍增&#xff0c;就是成倍增长。指我们进行递推时&#xff0c;如果状态空间很大&#xff0c;通常线性递推无法满足时空复杂度要求&#xff0c;那么可以通过成倍增长的方式&#xff0c;只递推状态空间中 2 的整…

V4L2-框架

1.概述 V4L2 是专门为linux 设备设计的一套视频框架&#xff0c;其主体框架在linux内核&#xff0c;可以理解为是整个linux系统上面的视频源捕获驱动框架。 相机驱动层位于HAL Moudle 与硬件层之间&#xff0c;借助linux 内核驱动框架&#xff0c;以文件节点的方式暴露接口给用…

V4L2学习笔记

首先附上&#xff0c;Linux内核网站&#xff1a; 入口 v4l2非常棒的一篇文章 入口 内核代码查看&#xff1a; 入口 一个博客文档&#xff1a; 入口 https://lwn.net/Articles/204545/ 别人整理 关于linux内核头函数&#xff1a; /usr/src/xxx 系列文 在其内部有media文件…

V4L2框架学习

V4L2框架 0 查看videodev2 0.1 头文件/usr/include/linux/videodev2.h 0.2 使用ioctl函数 使用ioctl函数 // 添加头文件 #include <unistd.h> #include <sys/ioctl.h> #include <linux/videodev2.h>int ioctl (int __fd, unsigned long int __request, ...…

V4L2介绍

V4L2介绍 V4L2介绍主要功能框架v4L2编程 V4L2介绍 V4L2是Video for linux2的简称,为linux中关于视频设备的内核驱动。在Linux中&#xff0c;视频设备是设备文件&#xff0c;可以像访问普通文件一样对其进行读写&#xff0c;摄像头在/dev/video*下&#xff0c;如果只有一个视频…

linux V4L2子系统——v4l2架构(7)之V4L2应用编程

linux V4L2子系统——v4l2架构&#xff08;7&#xff09;之V4L2应用编程 备注&#xff1a;   1. Kernel版本&#xff1a;5.4   2. 使用工具&#xff1a;Source Insight 4.0   3. 参考博客&#xff1a; &#xff08;1&#xff09;Linux V4L2子系统-应用层访问video设备&a…

[2022.8.15]v4l2-ctl基本使用方法

v4l2-ctl使用帮助可以参考&#xff1a;https://www.mankier.com/1/v4l2-ctl 1 v4l2-ctl --list-devices 列出所有设备 USB 2.0 Camera: USB Camera (usb-0000:00:14.0-9):/dev/video0/dev/video1 一个USB camera对应两个设备&#xff1a;一个是图像/视频采集&#xff0c;一…

V4L2应用层分析

V4L2应用层分析 一、总述二、例子 一、总述 V4L2&#xff0c;即Video for Linux 2&#xff0c;是第二代为Linux打造的音频、视频驱动。相比第一代V4L&#xff0c;V4L2支持更多的设备&#xff0c;同时更加稳定。现今的视频设备&#xff0c;如USB摄像头&#xff0c;基本都支持V4…

v4l2数据结构分析

v4l2数据结构分析 文章目录 v4l2数据结构分析Video4Linux2设备v4l2_device媒体设备media_deviceVideo4Linux2子设备v4l2_subdevVideo4Linux2子设备的操作集v4l2_subdev_opsVideo4Linux2子设备的内部操作集v4l2_subdev_internal_opsVideo4Linux2控制处理器v4l2_ctrl_handlerVide…

摄像头V4L2编程应用开发

1.V4L2简介 Video for Linux two(Video4Linux2)简称V4L2&#xff0c;是V4L的改进版。V4L2是linux系统操作系统下一套用于采集图片、视频、和音视频数据的通用API接口&#xff0c;配合适当的视频采集设备和相应的驱动程序&#xff0c;可以实现图片、视频、音频等的采集。 在linu…

V4L2框架

前言 在分析v4l2之前最好具有的知识&#xff1a; 1.字符设备,因为v4l2是被枚举为字符设备。 2.内存分配和映射,比如相关数据结构的分配和buffer。 3.DMA&#xff0c;因为v4l2的数据传输用到了DMA。 4.I2C&#xff0c;因为很多传感器都是用的i2c接口。 5.文件系统的基本操作&am…

V4L2系列 之 V4L2驱动框架

目录 前言一、V4L2驱动框架概览1、应用层 -》中间层-》驱动层2、主要代码文件(Linux 4.19版本内核) 二、怎么写V4L2驱动1、如何写一个设备的驱动&#xff1f;2、Video设备主要结构体3、怎么写V4L2驱动 三、V4L2的调试工具1、v4l2-ctl2、dev_debug3、v4l2-compliance 前言 本篇文…

V4L2框架概述

原文链接 本文开启 linux 内核 V4L2 框架部分的学习之旅&#xff0c;本文仅先对 V4L2 的框架做一个综述性的概括介绍&#xff0c;然后接下来的文章中会对 V4L2 框架的各个子模块进行一个全面的介绍&#xff0c;包括每一部分的实现原理&#xff0c;如何使用&#xff0c;用在什么…

V4l2框架分析

Table of Contents 1.V4L2框架概述 1.1 v4l2设备应用层流程 1.2 内核V4L2模块 1.2.1 video_device 1.2.2 v4l2_subdev 1.2.3 videobuf2 2. video_device结构体 2.1 图像处理模块 2.2 video_device处理流程 2.2.1 video_device 结构体成员介绍: 3. video_buf2 3.1 …

V4L2

V4L2(video 4 linux 2) V4L2有一段历史了。大约在1998的秋天&#xff0c;它的光芒第一次出现在Bill Dirks 的眼中。经过长足的发展&#xff0c;它于2002年11 月&#xff0c;发布2.5.46 时&#xff0c;融入了内核主干之中。然而直到今天&#xff0c;仍有一部分内核驱不支持新的A…

V4L2简介

http://work-blog.readthedocs.org/en/latest/v4l2%20intro.html 第一章 V4L2简介 1.1、什么是v4l2 V4L2&#xff08;Video4Linux的缩写&#xff09;是Linux下关于视频采集相关设备的驱动框架&#xff0c;为驱动和应用程序提供了一套统一的接口规范。 V4L2支持的设备十分广泛&…

我们一起学linux之V4L2摄像头应用流程

一、概述 Video for Linuxtwo(Video4Linux2)简称V4L2&#xff0c;是V4L的改进版。V4L2是linux操作系统下用于采集图片、视频和音频数据的API接口&#xff0c;配合适当的视频采集设备和相应的驱动程序&#xff0c;可以实现图片、视频、音频等的采集。在远程会议、可视电话、视频…

深入学习Linux摄像头(一)v4l2应用编程

深入学习Linux摄像头&#xff08;一&#xff09;v4l2应用编程 一、什么是v4l2 二、v4l2 API介绍 2.1 Querying Capabilities 2.2 Application Priority 2.3 Device Inputs and Outputs 2.4 Video Standards 2.5 Camera Control Reference 2.6 Image Format 2.7 Cropping, compo…

V4L2驱动框架详解

1. V4L2框架概述 1.1 v4l2设备应用层流程 1.2 内核V4L2模块 2 2. video_device 2.1图像处理模块 2.2 video注册流程 3. videobuf2 3.1 与video device的关系: 3.2 buffer类型 3.3 vb2_ops回调函数 3.4 mmap 流程 4. Subdev 4.1 概念 4.2 subdev注册流程 5. media fra…