倍增算法笔记

主要应用场景

RMQ:区间最值问题
LCA:最近公共祖先问题

RMQ问题——区间最值

如果用数组f[N]存储,用数组a[i][j]表示从第i个数起连续 2^j 个数中的最大值,[i,i + 2^j - 1],显然a[i][0] = f[i],则很容易得到状态转移方程:

a[i][j] = max(a[i][j - 1], a[i + 2^(j - 1)][j - 1])

图解

那么我们只需要对开始时,对于数组a进行预处理。我们先更新所有长度为0的情况a[i][0] = f[i]。然后,通过2个1元素的最值a[i][0]获得1个2元素的最值a[i][1],依次类推。
由于这里第二维j表示的是从i起,长度为2^j个数,所以j最大为logn,这里的复杂度应该是O(nlogn)。
此时,对于每一次询问的复杂度为O(1)
如果我们查询区间为[l,r],那么此时区间长度为 (r - l + 1),所以取 k = log(r - l + 1),可以将询问转换成 max(l,r) = max(a[l][k], a[r - (1 << k) + 1][k])。
其中,a[l][k]表示的是区间[l, l + 2^k - 1], a[r - 2^k + 1][k]表示的区间是[r - 2^k + 1, r]。

参考代码

参考例题:洛谷 P3865 【模板】ST 表

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6 + 3;
int n, t, arr[N][32];int query(int l, int r)
{int k = (int)(log((r - l + 1) * 1.0) / log(2.0));return max(arr[l][k], arr[r - (1 << k) + 1][k]);
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >> n >> t;for (int i = 1; i <= n; ++i)cin >> arr[i][0];for (int j = 1; j <= (int)(log(n * 1.0) / log(2.0)); ++j){for (int i = 1; i + (1 << j) - 1 <= n; ++i){arr[i][j] = max(arr[i][j - 1], arr[i + (1 << (j - 1))][j - 1]);}}while (t--){int l, r;cin >> l >> r;cout << query(l, r) << '\n';}
}

LCA问题——最近公共祖先

参考例题:

  1. 洛谷 P3379 【模板】最近公共祖先(LCA)
  2. 蓝桥OJ 最近公共祖先LCA查询

要求两个点的LCA,先将这两个点调整到同一高度(结点高度大的向上跳),之后两个结点同时往上跳,当他们到达同一高度时,该结点即为他们的LCA。
这里关键的是预处理,将每个结点的向上的父节点全部记录下来,方便结点向上跳时候使用。

例1参考代码(C++)

#include <bits/stdc++.h>
using namespace std;
// 2^logn 需要大于 N
const int N = 500003, logn = 22;
struct zzz {int t, nex;
}e[N << 1]; 
int head[N], tot;
void add(int x, int y) {e[++tot].t = y;e[tot].nex = head[x];head[x] = tot;
}
int depth[N], fa[N][logn], lg[N];
void dfs(int now, int fath) {fa[now][0] = fath; depth[now] = depth[fath] + 1;for(int i = 1; i <= lg[depth[now]]; ++i)fa[now][i] = fa[fa[now][i-1]][i-1];for(int i = head[now]; i; i = e[i].nex)if(e[i].t != fath) dfs(e[i].t, now);
}
int LCA(int x, int y) {if(depth[x] < depth[y]) swap(x, y);while(depth[x] > depth[y])x = fa[x][lg[depth[x]-depth[y]] - 1];if(x == y) return x;for(int k = lg[depth[x]] - 1; k >= 0; --k)if(fa[x][k] != fa[y][k])x = fa[x][k], y = fa[y][k];return fa[x][0];
}
int main() {int n, m, s; scanf("%d%d%d", &n, &m, &s);// 建树for(int i = 1; i <= n-1; ++i) {int x, y; scanf("%d%d", &x, &y);add(x, y); add(y, x);}// 预处理for(int i = 1; i <= n; ++i)lg[i] = lg[i-1] + (1 << lg[i-1] == i);dfs(s, 0);for(int i = 1; i <= m; ++i) {int x, y; scanf("%d%d",&x, &y);printf("%d\n", LCA(x, y));}return 0;
}

例2参考代码

#include <bits/stdc++.h>
using namespace std;
// 2^logn 需要大于 N
const int N = 1e5 + 3, logn = 20;
class TreeEdge
{
public:int to, nex;
} edge[N << 1];
// head
int head[N], tot;
void add(int x, int y)
{edge[++tot].to = y;edge[tot].nex = head[x];head[x] = tot;
}
int n, q, depth[N], f[N][logn], lg[N];void dfs(int now, int fath)
{f[now][0] = fath, depth[now] = depth[fath] + 1;for (int i = 1; i <= lg[depth[now]]; ++i)f[now][i] = f[f[now][i - 1]][i - 1]; // 2^(i - 1) * 2^(i - 1) = 2^ifor (int i = head[now]; i; i = edge[i].nex)if (edge[i].to != fath)dfs(edge[i].to, now);
}int lca(int a, int b)
{if (depth[a] < depth[b])swap(a, b);while (depth[a] > depth[b])a = f[a][lg[depth[a] - depth[b]] - 1];if (a == b)return a;for (int k = lg[depth[a]] - 1; k >= 0; --k)if (f[a][k] != f[b][k])a = f[a][k], b = f[b][k];return f[a][0];
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >> n;for (int i = 1; i < n; ++i){int u, v;cin >> u >> v;add(u, v), add(v, u);}for (int i = 1; i <= n; ++i)lg[i] = lg[i / 2] + 1;dfs(1, 0);cin >> q;while (q--){int a, b;cin >> a >> b;cout << lca(a, b) << '\n';}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/648489.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读书笔记-《数据结构与算法》-摘要11[Divide and Conquer - 分治法]

在计算机科学中&#xff0c;分治法是一种很重要的算法。分治法即『分而治之』&#xff0c;把一个复杂的问题分成两个或更多的相同或相似的子问题&#xff0c;再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解&#xff0c;原问题的解即子问题的解的合并。这个思…

电商API接口|爬虫案例|采集某东商品评论信息

前言&#xff1a; 平常大家都有网上购物的习惯&#xff0c;在商品下面卖的好的产品基本都会有评论&#xff0c;当然也不排除有刷评论的情况&#xff0c;因为评论会影响我们的购物决策。今天主要分享用pythonre正则表达式获取京东商品评论。API接口获取京东平台商品详情SKU数据…

11k+ star 一款不错的笔记leanote安装教程

特点 支持普通模式 支持markdown模式 支持搜索 安装教程 1.安装mongodb 1.1.下载 #下载 cd /opt wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.1.tgz 1.2解压 tar -xvf mongodb-linux-x86_64-3.0.1.tgz 1.3配置mongodb环境变量 vim /etc/profile 增…

电脑可以连接wifi,甚至可以qq聊天,但就是不能用浏览器上网,一直显示未检测出入户网线的解决方案

今天回到家&#xff0c;准备办公却发现电脑可以连接wifi&#xff0c;甚至可以qq聊天&#xff0c;但就是不能用浏览器上网&#xff0c;一直显示未检测出入户网线的解决方案&#xff0c;小白也可以看懂 以下有几种解决方案&#xff0c;不妨都试试&#xff0c;估计可以解决95%的相…

C#-前后端分离连接mysql数据库封装接口

C#是世界上最好的语言 新建项目 如下图所示选择框红的项目 然后新建 文件夹 Common 并新建类文件 名字任意 文件内容如下 因为要连接的是mysql数据库 所以需要安装 MySql.Data.MySqlClient 依赖; using MySql.Data.MySqlClient; using System.Data;namespace WebApplication1.…

Django 为应用定制化admin独立后台

定制后界面 在应用目录下找到admin.py并进行编辑 from django.contrib.admin import AdminSite from .models import Question,Choiceclass PollsAdminSite(AdminSite):site_header"Admin-site-header"site_title"admin-site-title"index_title"admi…

Conda 使用environment.yml创建一个新的Python项目

Conda系列&#xff1a; 翻译: Anaconda 与 miniconda的区别Miniconda介绍以及安装Conda python运行的包和环境管理 入门Conda python管理环境environments 一 从入门到精通Conda python管理环境environments 二 从入门到精通Conda python管理环境environments 三 从入门到精通…

Ansible自动化运维(三)Playbook 模式详解

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

未来已来:OJAC诚邀您与张立赛博士解锁GPT Store的无限潜力!

亲爱的伙伴们&#xff01;本月31日晚上8:30&#xff0c;我们近屿智能OJAC的培训讲师——哈尔滨工业大学博士毕业生、前之江实验室资深研究员张立赛博士&#xff0c;将为我们带来一场深度技术更新讲座&#xff0c;深度探讨GPT Store的最新发展。 本次讲座将从GPT Store的基本概念…

什么是互联网打工人都需要知道的API?电商API是什么?

我们生活在一个科技主导的世界。在这里&#xff0c;数据无处不在。作为许多不同产品的用户&#xff0c;我们所追寻的不再是某一个能将工作完成的最佳产品&#xff0c;而是一个不仅能有效完成工作&#xff0c;同时也与我们所使用的其他工具完美兼容的产品。因此&#xff0c;了解…

欧氏、曼哈顿、马氏距离

马氏距离&#xff08;Mahalanobis Distance&#xff09;、欧氏距离&#xff08;Euclidean Distance&#xff09;、曼哈顿距离&#xff08;Manhattan Distance&#xff09;是常用的距离度量方式&#xff0c;它们在数据分析、模式识别、聚类等领域中经常被使用。 欧氏距离&#…

3D建模素材网站的特点有哪些?

3D建模素材网站的特点主要包括丰富多样的模型种类、高质量的模型、实时预览功能、易于使用、价格合理以及社区互动等。这些特点使得3D建模素材网站成为设计师们不可或缺的资源之一&#xff0c;帮助他们快速高效地完成设计工作。 那么3D建模素材网站的特点有哪些? 1、模型种类丰…

【漏洞复现】上海冰峰ICEFLOW VPN信息泄露漏洞

Nx01 产品简介 上海冰峰计算机网络技术有限公司是国内VPN、流量管理、行为管理、链路负载均衡、下一代防火墙设备供应商和IT价值解决方案提供商。冰峰网络reporter系统是一套数据报表管理系统。 Nx02 漏洞描述 上海冰峰计算机网络技术有限公司ICEFLOW VPN Router系统存在信息泄…

eNSP学习——利用单臂路由实现VLAN间路由

目录 原理概述 实验内容 实验目的 实验步骤 实验拓扑 实验编址 配置步骤 创建VLAN并配置Access、Trunk接口 配置路由器子接口和IP地址 配置路由器子接口封装VLAN 测试结果 原理概述 在以太网中&#xff0c;通常会使用VLAN技术隔离二层广播域来减少广播的影响&#…

langchain + hugginface入门体验

简介 本文记录一次使用langchain调用openai并部署在huggingface上的经历 安装环境依赖 我的python版本是3.9 pip install langchain pip install openai代码 app.py import streamlit as st # from langchain_community.chat_models import ChatOpenAI from langchain_openai …

w23靶场安装

一、实验环境 服务器&#xff1a;phpstudyv8.1.13 靶场&#xff1a;Bees、sdcms、cpms、khbc二、实验目的 提供一个靶场环境 三、实验步骤 bees靶场安装 1.启动小皮的apache和mysql 2.在小皮V8.1.1.3版本上创建bees网站&#xff0c;选择的php版本最好在5.x&#xff0c;不…

聚道云软件连接器:打通金蝶云星空与招商银行CBS,提升企业财务和银行业务效率

【客户介绍】 某企业是一家从事电子商务的企业&#xff0c;随着业务的不断扩大&#xff0c;对于财务管理和银行业务的需求也越来越高。该企业希望能够实现财务和银行业务的自动化处理&#xff0c;提高工作效率。由于业务的不断发展&#xff0c;企业面临着越来越多的资金管理挑…

强化学习14——DDPG算法

在线策略算法的样本效率比较低&#xff0c;而在DNQ算法中&#xff0c;做到了离线策略学习&#xff0c;但是只能处理动作空间有限的环境。如果动作空间无限&#xff0c;可将动作空间离散化&#xff0c;但比较粗糙&#xff0c;无法惊喜控制。深度确定性策略梯度DDPG&#xff08;d…

网站SSL证书怎么获取?

获取SSL证书的途径通常包括以下几种&#xff1a; 1. 通过受信任的证书颁发机构&#xff08;CA&#xff09;购买&#xff1a; - 你可以直接从知名的证书颁发机构如JoySSL、GeoTrust、DigiCert等处购买。 - 这些机构提供不同类型的SSL证书&#xff0c;包括域名验证(DV)、组…

「JavaSE」抽象类接口3

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;快来卷Java啦 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 抽象类&接口3 &#x1f349;Clonable 接口和深拷贝&#x1f34c;浅拷贝和深拷贝 &#x1f349;Object类&#x1f349;抽象类…