国庆郑州集训day3:数据结构

本文介绍了数据结构中的核心概念,包括字符串Hash、Trie树、并查集、优先队列、线段树及树状数组等。针对每种数据结构的特点和应用场景进行了详细解析,并提供了多个典型例题。

数据结构

哈希字符串

字符串Hash:一种从字符串到整数的映射。

BKDR-Hash

》竞赛中常用的 hash 策略
》把字符串视为一个 base 进制的大整数,对某个质数 P 取模得到 hash 值
》sum_i = (sum_{i-1} *base + str_i) mod P
》base 可以取 31、131、13131 等,需要满足 base > |字符集|
》P 取 long long 范围内一个质数,注意溢出问题
》使用 unsigned long long 自然溢出可以视为对 2^64 取模
》但是可能被卡(对任意base)
》害怕 Hash 被卡的同学,也可以选择双 hash(常数翻倍)。

常用技巧

给定字符串 S,预处理出它的前缀 Hash 函数;同时计算好 mod P 意义下 base 的幂次表
sum[i] = (sum[i - 1] * base + str[i]) % P ////sum[i]为前i位的hash值
pw[i] = (pw[i - 1] * base) % P
基础应用:
提取一段子串的 hash 值
合并两个串的 hash 值
O(\log n) 计算两个子串的 lcp 和字典序大小

P:企鹅QQ

给定 N 个长度均为 L 的串
问有多少对字符串满足:恰好有一位对应不同
N <= 30000, L <= 200

ans:枚举删掉每一个位置,用 Hash 来进行答案统计

Trie树

又称字母树,可以用来维护字符串集合
优化思想是,利用字符串的公共前缀来减少查询时间,最大限度地减少无意义的比较
结构:有根树,每条边上存有一个字符
从根到每个叶子的路径上经过的字符写下来,对应了一个字符串

支持插入、查找、删除。

经典例题

(1)
给定 2 N 个字符串,你需要将它们配对起来
两个字符串 x、y 配对的得分是它们的 lcp 长度
最大化得分
N*<= 10^5,字符串总长 <= 2 * 10^6
建出 trie 树,两个串的 LCP 即为它们的 LCA 的深度
使用贪心算法,按照树的 DFS 序列配对

(2)
给定一棵有根树,每条边有权值 w_i
求树上的一条简单路径,使得路径经过的边权异或和最大
N <= 2 * 10^5, w_i <= 10^9
记录 dis[a] 表示 a 到根的链的异或和
考虑 x、y 之间的链的异或和,设 LCA 为 z
= (dis[x] ^ dis[z]) ^ (dis[y] ^ dis[z]) = dis[x] ^ dis[y]
不难发现与 z 无关!
于是问题转化为,给定 N 个数,选出两个使得异或和最大
考虑枚举两个数之一 x,我们想在其它数中找到一个与 x 的异或和最大
从高到低考虑每一位,尽可能让更高位为 1
不难发现可以使用 Trie 树!
复杂度 O(N * 32)

并查集

原理

对每个集合,建立一个有根树的结构
令树的根为整个集合的“代表”
想知道两个元素是否在同一集合,只需比较它们的代表
合并时,将一棵树接到另一棵下边即可

优化策略

路径压缩
按秩合并(不考虑路径压缩的情况下,秩为该树的最大深度(最深叶节点的深度))
可以证明,使用这两种优化的并查集复杂度为 O(α(n))
绝大多数情况这个值不大于 5,可以认为是线性的

应用

最小生成树的 Kruskal 算法
Tarjan’s off-line LCA Algorithm

带权

在一些应用中,可以在每个点上额外维护一些信息,表示“它与父亲”之间的关系
进而尝试推算集合中任意两个元素之间的关系

经典例题

帮派:
某市有两个帮派,有 N 个人,每个人属于两个帮派之一。
给定 M 个事件:
1 x y,表示告诉你 x 和 y 属于同一帮派
2 x y,表示告诉你 x 和 y 不属于同一帮派
3 x y,表示请你推理 x 和 y 之间的关系
N <= 5 * 10^5, M <= 10^6
给每个人额外维护一个标记 rel[x] 表示 x 和 x 的父亲的关系
由 rel[x] 和 rel[fa[x]] 可以推算 x 和 fa[fa[x]] 的关系。。。以此类推可以推算 x 和 Root[x] 的关系
于是任意两个人只要在同一连通块,就能推算他们的关系
问题:这个并查集如何使用路径压缩优化呢?

只按秩合并

经典例题

给定 N 个点,支持 M 个操作:
1 x y,在 x 和 y 之间连边
2 x y,询问 x 和 y 是否连通,如果是,那它们最早在哪一次操作之后连通的
N <= 2 * 10^5, M <= 5 * 10^5
@货车运输
离线的时候可以建树倍增 blabla。。。
强制在线呢?
只按秩合并,link(x, y, tim) 时,我们在 Root[x] 和 Root[y] 之间连一条边权为 tim 的边
询问 (x, y) 时,找到 x 和 y 之间边权最大的边即可
这种算法‘的复杂度是容易证明 O(\log N) 的
正确性?

优先队列

支持这样几种操作的数据结构:
插入一个优先级为 key 的元素
询问优先级最高的元素
删除优先级最高的 / 任意一个元素
升高一个元素的优先级值
优先队列一般使用堆来实现
最经典的堆即为大名鼎鼎的二叉堆

二叉堆

二叉堆是一个完全二叉树结构,并且它具有堆性质:
每个点的优先级高于它的两个孩子(如果有)
可以用一个数字来存储二叉堆,避免指针:
1 是根结点
对于 x,它的左右孩子分别是 2x 和 2x+1
容易验证 N 个点的二叉堆,它用到的数组即为 1 ~ N
给定一个大小为 N 的数组,我们可以 O(N) 的建堆(How?

操作

随着操作的进行,二叉堆的“堆性质”可能会遭到破坏,为此我们定义两种调整操作,来维护二叉堆的堆性质保持不变
向上调整:
当一个点的优先级升高时,我们需要向上调整
比较它和它的父亲的优先级,它的优先级高就与父亲交换位置并递归进行
向下调整:
当一个点的优先级降低时,我们需要向下调整
比较它和它左右儿子中优先级较高的那个,它的优先级低就与儿子交换并递归下去
容易验证两种操作的复杂度均为 O(\log N)

线段树入门

线段树是一种二叉搜索树,一般可以用来维护序列的子区间

结构

对一个长度为 n 的序列建线段树,根结点即表示 [1, n]
对于一个表示 [l, r] 的节点:
若 l = r,则它是叶子
否则,令 m = (l + r) / 2,它有左右两个孩子,分别记为:[l, m] 和 [m + 1, r]
不难验证,这样一个线段树中有 2N - 1 个节点,并且树的深度是 O(\log N) 级别

原理

线段树的优化思想:
根据问题的要求,用每个节点维护它对应的子区间中、可以高效合并的相关信息
在动态的序列问题中,对于修改操作没有动过的部分。我们可以考虑把这些地方的求解的结果保存并复用,从而达到优化程序效率、降低复杂度的目的

例题

(1)给定一个长度为 N 的序列,支持:
修改一个位置的值
查询一个子区间的元素和
线段树每个节点维护对应子区间的和
区间覆盖:
对于一个区间 [l, r],我们可以将其分解为线段树上 O(\log N) 个节点的并;
这里的分解是指,我们选取的区间并起来恰好为 [l, r]。且选择的区间不会相互重叠
修改操作中,为了维护线段树性质,需要修改总共 O(\log N) 个节点
查询操作,将区间拆为 O(\log N) 个区间的并,从而优化查询的复杂度
总时间复杂度 O(\log N)

(2)有 N 头牛,第 i 头牛的高度为 i
现在这 N 头牛随意站成一列,第 i 头牛看到前面有 a[i] 个牛的比它高
求每个位置的牛的高度
N <= 2 * 10^5
(3)等差子序列
给定一个 1 ~ N 的排列
问:是否存在一个长度 >= 3 的等差子序列
N <= 2 * 10^5
考虑是否存在一个以 x 为中项的、长度为 3 的等差序列
这等价于:存在 k > 0,使得 x-k 和 x+k 在 x 的两侧
我们用两个二进制数,分别记录:在 x 左侧的, 1 ~ x-1 和 x+1 ~ N 的存在情况
于是,判断 k 的存在性与判断两个二进制数的相等是等价的
从左到右扫描每一个数,用线段树维护、查询每一段连续的数的存在情况(使用 BKDR-hash),就能支持快速合并了

(4)给定一个序列,支持:
区间加上一个整数 x
询问区间的和
修改操作暴力进行,复杂度为 O(N)
使用懒标记
把修改操作分解为 O(\log N) 个线段树区间的并
在这些线段树区间上打一个“整体被加了 x” 的标记
将来必要的时候再将标记下放

树状数组

一种支持单点修改和查询前缀和的数据结构
复杂度为 O(\log N),但是常数很小

原理

定义 lowbit(x),表示将 x 写成二进制后,只保留二进制下最低一个 1 对应的整数
例:lowbit(1001100) = 100, lowbit(1000) = 1000
十进制:lowbit(76)=4, lowbit(8) = 8
对一个数组 a[],我们构造数组 c[],其中
c[i] = sum (. a[i - lowbit(i) + 1 … i] )
巧妙的事情来了:
我们查询 a[] 的前缀和只需要访问 c 中 log N 个节点
修改 a[] 中任意一个元素的值,只需要同时修改 c 中的 log N 个节点
于是可以在 O(\log N) 的时间内支持单点修改、前缀和查询

树状数组 vs 线段树

复杂度均为 O(\log N)
优点:

树状数组常数小、跑得快;线段树常 数较大,跑得稍慢
树状数组相比线段树好实现
树状数组可以比较简单地推广到二维

不足:

树状数组的功能是线段树的子集

二维树状数组

对二维数组 a[][],维护 c[][] 表示
c[i][j] = sum( a [ i-lowbit(i)+1 … i] [ j-lowbit(j)+1 … j] )
可以支持二维数组的单点修改、查询前缀矩形的和
复杂度 O(\log^2 N)

区间加+区间查询

想支持对数组 a[] 的区间加整数、区间查询和
考虑 a[] 的差分数组 b[i] = a[i] - a[i - 1]
区间加对 b[] 只修改两个位置!
同时,为了支持查询 a[] 的前缀和,经过一番推导,发现只需维护 b[i] 和 i * b[i] 的前缀和即可
复杂度 O(\log N)

标题SpringBoot智能在线预约挂号系统研究AI更换标题第1章引言介绍智能在线预约挂号系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景与意义阐述智能在线预约挂号系统对提升医疗服务效率的重要性。1.2国内外研究现状分析国内外智能在线预约挂号系统的研究与应用情况。1.3研究方法及创新点概述本文采用的技术路线、研究方法及主要创新点。第2章相关理论总结智能在线预约挂号系统相关理论,包括系统架构、开发技术等。2.1系统架构设计理论介绍系统架构设计的基本原则和常用方法。2.2SpringBoot开发框架理论阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.3数据库设计与管理理论介绍数据库设计原则、数据模型及数据库管理系统。2.4网络安全与数据保护理论讨论网络安全威胁、数据保护技术及其在系统中的应用。第3章SpringBoot智能在线预约挂号系统设计详细介绍系统的设计方案,包括功能模块划分、数据库设计等。3.1系统功能模块设计划分系统功能模块,如用户管理、挂号管理、医生排班等。3.2数据库设计与实现设计数据库表结构,确定字段类型、主键及外键关系。3.3用户界面设计设计用户友好的界面,提升用户体验。3.4系统安全设计阐述系统安全策略,包括用户认证、数据加密等。第4章系统实现与测试介绍系统的实现过程,包括编码、测试及优化等。4.1系统编码实现采用SpringBoot框架进行系统编码实现。4.2系统测试方法介绍系统测试的方法、步骤及测试用例设计。4.3系统性能测试与分析对系统进行性能测试,分析测试结果并提出优化建议。4.4系统优化与改进根据测试结果对系统进行优化和改进,提升系统性能。第5章研究结果呈现系统实现后的效果,包括功能实现、性能提升等。5.1系统功能实现效果展示系统各功能模块的实现效果,如挂号成功界面等。5.2系统性能提升效果对比优化前后的系统性能
在金融行业中,对信用风险的判断是核心环节之一,其结果对机构的信贷政策和风险控制策略有直接影响。本文将围绕如何借助机器学习方法,尤其是Sklearn工具包,建立用于判断信用状况的预测系统。文中将涵盖逻辑回归、支持向量机等常见方法,并通过实际操作流程进行说明。 一、机器学习基本概念 机器学习属于人工智能的子领域,其基本理念是通过数据自动学习规律,而非依赖人工设定规则。在信贷分析中,该技术可用于挖掘历史数据中的潜在规律,进而对未来的信用表现进行预测。 二、Sklearn工具包概述 Sklearn(Scikit-learn)是Python语言中广泛使用的机器学习模块,提供多种数据处理和建模功能。它简化了数据清洗、特征提取、模型构建、验证与优化等流程,是数据科学项目中的常用工具。 、逻辑回归模型 逻辑回归是一种常用于分类任务的线性模型,特别适用于二类问题。在信用评估中,该模型可用于判断借款人是否可能违约。其通过逻辑函数将输出映射为0到1之间的概率值,从而表示违约的可能性。 四、支持向量机模型 支持向量机是一种用于监督学习的算法,适用于数据维度高、样本量小的情况。在信用分析中,该方法能够通过寻找最佳分割面,区分违约与非违约客户。通过选用不同核函数,可应对复杂的非线性关系,提升预测精度。 五、数据预处理步骤 在建模前,需对原始数据进行清理与转换,包括处理缺失值、识别异常点、标准化数值、筛选有效特征等。对于信用评分,常见的输入变量包括收入水平、负债比例、信用历史记录、职业稳定性等。预处理有助于减少噪声干扰,增强模型的适应性。 六、模型构建与验证 借助Sklearn,可以将数据集划分为训练集和测试集,并通过交叉验证调整参数以提升模型性能。常用评估指标包括准确率、召回率、F1值以及AUC-ROC曲线。在处理不平衡数据时,更应关注模型的召回率与特异性。 七、集成学习方法 为提升模型预测能力,可采用集成策略,如结合多个模型的预测结果。这有助于降低单一模型的偏差与方差,增强整体预测的稳定性与准确性。 综上,基于机器学习的信用评估系统可通过Sklearn中的多种算法,结合合理的数据处理与模型优化,实现对借款人信用状况的精准判断。在实际应用中,需持续调整模型以适应市场变化,保障预测结果的长期有效性。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
Foodpanda 的全面记录,包含 6000 条精心整理的记录,涵盖了从客户人口统计信息到订单、支付、评价和配送细节的各个方面。它为数据分析师和研究人员提供了一个丰富的资源,可用于深入分析和洞察 Foodpanda 的业务运营和客户行为。 数据集内容客户人口统计信息:数据集详细记录了客户的年龄、性别、收入水平、地理位置等基本信息。这些信息有助于了解不同客户群体的特征,为精准营销和客户细分提供数据支持。 订单信息:每条记录都包含了订单的日期、时间、金额以及购买的商品或服务。通过分析这些数据,可以发现客户的购买习惯和偏好,例如哪些时间段是订单高峰期,哪些菜品最受欢迎。 支付信息:数据集中还包含了支付方式、支付状态和支付金额等信息。这些数据可以帮助分析不同支付方式的使用频率,以及支付成功率等关键指标。 评价信息:客户对订单、服务或产品的评分和评论也被记录在数据集中。这些评价数据对于情感分析和客户满意度研究至关重要,能够帮助 Foodpanda 了解客户的真实反馈,从而改进服务质量。 配送细节:数据集还详细记录了配送时间、配送地址和配送状态等信息。通过分析这些数据,可以优化配送路线和时间,提高客户满意度。 数据集的应用场景:客户行为分析:通过分析客户的购买习惯、偏好和评价,可以更好地了解客户需求,从而提供更个性化的服务。 客户流失预测:利用数据集中的客户行为和评价数据,可以构建模型预测哪些客户可能会流失,以便提前采取措施挽留。 客户细分:根据客户的人口统计信息和购买行为,可以将客户划分为不同的群体,为每个群体提供定制化的服务和营销策略。 销售趋势分析:通过分析订单数据,可以发现销售的增长或下降趋势,为业务决策提供依据。 情感洞察:通过分析客户的评价和评论,可以了解客户对产品或服务的情感倾向,及时发现潜在问题并加以改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值