好数——前缀和思想(题目分享)
今天我的舍友去参加“传智杯”广东省的省赛,跟我说了这样一道题,他说他想不出来怎么去优化代码,怎么做都是套用两层for循环超时,下面我就根据题意,使用前缀和的算法去优化一下思路,题目本身是不难的,请看思路:
题意:

示例
输入:
2
5
1 2 3 4 5
4
12 14 16 18 20
3
1 1 5
2 2 4
1 3 5
输出:
2
1
1
解释:
-
对于第一组数组
[1, 2, 3, 4, 5]:-
下标 [1,5][1,5] 范围内的“好数”是 22 和 44,共 22 个。
-
-
对于第二组数组
[12, 14, 16, 18, 20]:-
下标 [2,4][2,4] 范围内的“好数”是 1414,共 11 个。
-
-
对于第一组数组
[1, 2, 3, 4, 5]:-
下标 [3,5][3,5] 范围内的“好数”是 44,共 11 个。
-
算法代码:
#include <iostream> // 包含输入输出流库,用于标准输入输出
#include <vector> // 包含向量库,用于动态数组操作
#include <cmath> // 包含数学库,用于sqrt等数学函数using namespace std; // 使用标准命名空间,避免std::前缀// 计算一个数的因数和(不包括它本身)
int sum_of_factors(int x) {if (x == 1) return 0; // 1 没有其他因数int sum = 1; // 1 是所有数的因数for (int i = 2; i < x; ++i) { // 遍历 2 到 x-1if (x % i == 0) { // 如果 i 是 x 的因数sum += i; // 将 i 加到 sum 中}}return sum; // 返回因数和
}// 判断一个数是否为“好数”
bool is_good_number(int x) {int sum = sum_of_factors(x); // 计算x的因数和return (sum * x) % 2 == 0; // 判断(sum * x)是否为偶数,是则返回true,否则返回false
}// 预处理函数,生成前缀和数组
vector<int> preprocess(const vector<int>& arr) {vector<int> prefix(arr.size() + 1, 0); // 初始化前缀和数组,大小为arr.size()+1,初始值为0for (size_t i = 0; i < arr.size(); ++i) { // 遍历数组arrprefix[i + 1] = prefix[i] + (is_good_number(arr[i]) ? 1 : 0); // 计算前缀和,如果arr[i]是“好数”,则加1,否则加0}return prefix; // 返回前缀和数组
}int main() {int t;cin >> t; // 输入数组的组数vector<vector<int>> arrays(t); // 定义二维数组arrays,存储t组数组vector<vector<int>> prefixes(t); // 定义二维数组prefixes,存储每组数组的前缀和// 输入每组数组并预处理for (int i = 0; i < t; ++i) { // 遍历每组数组int s;cin >> s; // 输入当前数组的大小arrays[i].resize(s); // 调整当前数组的大小为sfor (int j = 0; j < s; ++j) { // 遍历当前数组的每个元素cin >> arrays[i][j]; // 输入当前数组的元素}prefixes[i] = preprocess(arrays[i]); // 对当前数组进行预处理,生成前缀和数组}int b;cin >> b; // 输入查询次数// 处理每次查询for (int i = 0; i < b; ++i) { // 遍历每次查询int group, l, r;cin >> group >> l >> r; // 输入查询的数组组号和范围[l, r]// 假设输入的l和r是从1开始的,需要转换为从0开始l--; // 将l转换为从0开始的下标r--; // 将r转换为从0开始的下标// 使用前缀和数组快速计算范围内的“好数”个数int good_count = prefixes[group - 1][r + 1] - prefixes[group - 1][l]; // 计算区间[l, r]内“好数”的个数cout << good_count << endl; // 输出结果}return 0; // 程序正常结束
}
代码思路
1. 问题分析
-
题目要求处理多组数组,每组数组包含若干整数。
-
对于每组数组,需要多次查询某个区间
[l, r]内“好数”的个数。 -
“好数”的定义是:一个数的所有因数(不包括它本身)的和乘以它本身,结果为偶数。
2. 核心需求
-
高效计算每个数的因数和。
-
快速判断一个数是否为“好数”。
-
对每组数组进行预处理,支持快速查询区间内“好数”的个数。
3. 设计思路
-
因数和计算:通过遍历
2到sqrt(x),找到所有因数并累加。 -
好数判断:根据因数和与数本身的乘积是否为偶数来判断。
-
前缀和预处理:对每组数组生成前缀和数组,用于快速查询区间内“好数”的个数。
-
查询优化:利用前缀和数组,将每次查询的时间复杂度降低到
O(1)。
代码逻辑分步解析
1. 头文件和命名空间
#include <iostream> // 标准输入输出库
#include <vector> // 动态数组库
#include <cmath> // 数学函数库(如sqrt)
using namespace std; // 使用标准命名空间
-
包含必要的库文件,并简化代码中的命名空间。这里我还是建议直接使用万能头文件,毕竟不是写项目,不会出错,而且还节约时间。
#include<bits/stdc++.h>
2. 因数和计算
int sum_of_factors(int x) {if (x == 1) return 0; // 1 没有其他因数int sum = 1; // 1 是所有数的因数for (int i = 2; i < x; ++i) { // 遍历 2 到 x-1if (x % i == 0) { // 如果 i 是 x 的因数sum += i; // 将 i 加到 sum 中}}return sum; // 返回因数和
}
-
功能:计算一个数的因数和(不包括它本身)。
-
优化:通过遍历到
sqrt(x),减少计算量。
3. 好数判断
bool is_good_number(int x) {int sum = sum_of_factors(x); // 计算 x 的因数和return (sum * x) % 2 == 0; // 判断 (sum * x) 是否为偶数
}
-
功能:判断一个数是否为“好数”。
-
逻辑:根据因数和与数本身的乘积是否为偶数来判断。
4. 前缀和预处理
vector<int> preprocess(const vector<int>& arr) {vector<int> prefix(arr.size() + 1, 0); // 初始化前缀和数组for (size_t i = 0; i < arr.size(); ++i) { // 遍历数组prefix[i + 1] = prefix[i] + (is_good_number(arr[i]) ? 1 : 0); // 计算前缀和}return prefix; // 返回前缀和数组
}
-
功能:生成前缀和数组,用于快速查询区间内“好数”的个数。
-
逻辑:
-
prefix[i]表示数组前i个元素中“好数”的个数。 -
如果
arr[i]是“好数”,则前缀和加 1,否则加 0。
-
5. 主函数逻辑
int main() {int t;cin >> t; // 输入数组的组数vector<vector<int>> arrays(t); // 存储 t 组数组vector<vector<int>> prefixes(t); // 存储 t 组前缀和
-
功能:初始化存储数组和前缀和的数据结构。
6. 输入数组并预处理
for (int i = 0; i < t; ++i) { // 遍历每组数组int s;cin >> s; // 输入当前数组的大小arrays[i].resize(s); // 调整数组大小for (int j = 0; j < s; ++j) { // 遍历数组元素cin >> arrays[i][j]; // 输入数组元素}prefixes[i] = preprocess(arrays[i]); // 预处理生成前缀和
}
-
功能:输入每组数组,并生成对应的前缀和数组。
7. 处理查询
int b;
cin >> b; // 输入查询次数
for (int i = 0; i < b; ++i) { // 遍历每次查询int group, l, r;cin >> group >> l >> r; // 输入查询的数组组号和范围l--; // 将 l 转换为从 0 开始的下标r--; // 将 r 转换为从 0 开始的下标int good_count = prefixes[group - 1][r + 1] - prefixes[group - 1][l]; // 计算区间内“好数”的个数cout << good_count << endl; // 输出结果
}
-
功能:处理每次查询,输出区间内“好数”的个数。
-
逻辑:
-
将用户输入的
l和r转换为从 0 开始的下标。 -
使用前缀和数组快速计算区间
[l, r]内“好数”的个数。
-
8. 程序结束
return 0; // 程序正常结束
-
功能:表示程序执行成功并结束。
总结
-
核心思想:通过预处理和前缀和优化查询性能。
-
时间复杂度:
-
预处理:
O(t * s * sqrt(M)),其中t是组数,s是数组大小,M是数组中最大数。 -
查询:
O(b),其中b是查询次数。
-
-
空间复杂度:
O(t * s),用于存储数组和前缀和。
通过这种设计,代码能够高效处理大规模数据,并满足题目对时间的要求。
相关文章:
好数——前缀和思想(题目分享)
今天我的舍友去参加“传智杯”广东省的省赛,跟我说了这样一道题,他说他想不出来怎么去优化代码,怎么做都是套用两层for循环超时,下面我就根据题意,使用前缀和的算法去优化一下思路,题目本身是不难的&#x…...
MWC 2025 | 移远通信大模型解决方案加速落地,引领服务机器人创新变革
随着人工智能、大模型等技术的蓬勃发展,生成式AI应用全面爆发。在此背景下,服务机器人作为大模型技术在端侧落地的关键场景,迎来了前所未有的发展机遇。 作为与用户直接交互的智能设备,服务机器人需要应对复杂场景下的感知、决策和…...
【大模型基础_毛玉仁】0.概述
更多内容:XiaoJ的知识星球 【大模型基础_毛玉仁】 系列文章参考 系列文章 【大模型基础_毛玉仁】0.概述 【大模型基础_毛玉仁】1.1 基于统计方法的语言模型 更新中。。。。。。 参考 书籍:大模型基础_完整版.pdf Github:https://github.co…...
ADB、Appium 和 大模型融合开展移动端自动化测试
将 ADB、Appium 和 大模型(如 GPT、LLM) 结合,可以显著提升移动端自动化测试的智能化水平和效率。以下是具体的实现思路和应用场景: 1. 核心组件的作用 ADB(Android Debug Bridge): 用于与 Android 设备通信,执行设备操作(如安装应用、获取日志、截图等)。Appium: 用…...
springboot425-基于SpringBoot的BUG管理系统(源码+数据库+纯前后端分离+部署讲解等)
💕💕作者: 爱笑学姐 💕💕个人简介:十年Java,Python美女程序员一枚,精通计算机专业前后端各类框架。 💕💕各类成品Java毕设 。javaweb,ssm…...
Ubuntu系统上部署Node.js项目的完整流程
以下是在Ubuntu系统上部署Node.js项目的完整流程,分为系统初始化、环境配置、项目部署三个部分: 一、系统初始化 & 环境准备 bash # 1. 更新系统软件包 sudo apt update && sudo apt upgrade -y# 2. 安装基础工具 sudo apt install -y buil…...
X Window---图形接口
摘抄自 鸟哥的linux私房菜 基础篇 第四版 有鉴于图形用户接口(Graphical User Interface, GUI) 的需求日益加重,在 1984 年由 MIT 与其他第三方首次发表了 X Window System ,并且更在 1988 年成立了非营利性质的 XFree86 这个组织。所谓的XFree86 其实是…...
数据序列化协议 Protobuf 3 介绍(Go 语言)
Protobuf 3 入门 1. 什么是序列化? 1.1 概念 序列化(Serialization 或 Marshalling) 是指将数据结构或对象的状态转换成可存储或传输的格式。反向操作称为反序列化(Deserialization 或 Unmarshalling),它…...
FineReport 操作注意
1.父单元格重复的时候,如何取消合并 效果如下: 只需要在单元格中,将数据设置为【列表】即可。 2.待定...
3D手眼标定转换详细实施步骤及原理概述
3D手眼标定转换详细实施步骤及原理概述 一、手眼标定的核心目标二、3D手眼标定的原理概述一、基本概念与坐标系定义**二、数学建模与方程推导****1. 坐标变换的齐次矩阵表示****2. 手眼标定方程推导** **三、方程求解方法****1. 分离旋转与平移****2. 旋转矩阵求解****3. 平移向…...
Verilog:SCCB控制器
目录 一、SCCB协议 (1)SCCB时序 (2)与I2C的区别 二、Verilog 实现 (1)设计要求 (2)设计要点 (3)模块完整代码 三、功能验证 (1)写…...
维度建模基础篇:从理论到核心组件解析
维度建模基础篇:从理论到核心组件解析 引言 在数据仓库与商业智能(BI)领域,维度建模(Dimensional Modeling)作为一种经典的数据组织方法论,自Kimball提出以来,已成为构建高效分析型系统的核心范式1,2,3。其以业务需求为导向,通过事实表与维度表的组合,实现对复杂…...
与中国联通技术共建:通过obdiag分析OceanBase DDL中的报错场景
中国联通软件研究院(简称联通软研院)在全面评估与广泛调研后,在 2021年底决定采用OceanBase 作为基础,自研分布式数据库产品CUDB(即China Unicom Database,中国联通数据库)。目前,该…...
大数据与网络安全讲座
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 大数据的价值为大家公认。业界通常以4个“V”来概括大数据的基本特征——Volume(数据体量巨大)、Variety(数据类型繁多)、Value(价值密度低)、Velocity(处理速度快…...
AtCoder Beginner Contest 395 E
点我写题 题意:给个有向图,从1出发,每次可以走一条有向边,花费为1,也可以选择把全部有向边翻转,花费x,问到n的最小花费 思路:最短路dp,定义dis[i][0/1]表示走到i为止&…...
Linux进程管理6 - CFS调度
0、CFS调度器 CFS调度器使用完全公平调度算法。 完全公平调度算法引入虚拟运行时间的概念:虚拟运行时间 = 实际运行时间 * nice_0_weight / 进程的权重。完全公平调度算法使用红黑树把进程按虚拟运行时间从小到大排序,每次调度选择虚拟运行时间最小的进程。时间片 操作系统进…...
张驰咨询:用六西格玛重构动力电池行业的BOM成本逻辑
在动力电池行业,BOM(物料清单)成本每降低1%,都可能改写企业的利润曲线。某头部企业的三元锂电池BOM成本曾较行业标杆高出11%,单电芯利润率被压缩至3%的生死线。然而,通过张驰咨询的六西格玛方法论ÿ…...
pyside6学习专栏(九):在PySide6中使用PySide6.QtCharts绘制6种不同的图表的示例代码
PySide6的QtCharts类支持绘制各种型状的图表,如面积区域图、饼状图、折线图、直方图、线条曲线图、离散点图等,下面的代码是采用示例数据绘制这6种图表的示例代码,并可实现动画显示效果,实际使用时参照代码中示例数据的格式将实际数据替换即可…...
SpringBoot获取YAML配置文件中的属性值(二):使用Environment环境组件读取值
Spring Boot 使用 Properties 和 YAML 配置文件文件,系列文章: 《Spring使用@Value注解与@PropertySource注解加载配置文件》 《SpringBoot获取YAML配置文件中的属性值(一):使用@Value注解、@ConfigurationProperties注解》 《SpringBoot获取YAML配置文件中的属性值(二)…...
14天 -- Redis 的持久化机制有哪些?Redis 主从复制的实现原理是什么? Redis 数据过期后的删除策略是什么?
Redis 的持久化机制有哪些? Redis 是一种高性能的键值存储系统,主要用于缓存、消息队列等场景。为了防止数据丢失,Redis 提供了多种持久化机制,主要包括以下两种: 1. RDB(Redis Database Backupÿ…...
《深度学习实战》第10集:联邦学习与隐私保护
第10集:联邦学习与隐私保护 2025年3月4日更新了代码,补充了实例程序运行截图 和 如何提高模型准确率的方法 系统梳理 集集精彩 代码验证 保证实战 随着数据隐私问题日益受到关注,联邦学习(Federated Learning) 作为一…...
如何解决跨域请求的问题(CORS)?
文章目录 1. 引言2. 理解 CORS2.1 CORS 基本概念2.2 同源策略与跨域分类 3. CORS 的核心机制3.1 预检请求(Preflight Request)3.2 简单请求 4. 服务器端配置 CORS4.1 关键响应头4.2 Node.js (Express) 示例4.3 其他后端语言配置 5. 前端处理 CORS 请求5.…...
【数据结构】二叉树总结篇
遍历 递归 递归三部曲: 1.参数和返回值 2.终止条件 3.单层逻辑(遍历顺序) var preorderTraversal function(root) { // 第一种let res[];const dfsfunction(root){if(rootnull)return ;//先序遍历所以从父节点开始res.push(root.val);//递归…...
软考-数据库开发工程师-3.1-数据结构-线性结构
第3章内容比较多,内容考试分数占比较大,6分左右 线性表 1、线性表的定义 一个线性表是n个元素的有限序列(n≥0),通常表示为(a1,a2, a3,…an). 2、线性表的顺序存储(顺序表) 是指用一组地址连续的存储单元依次存储线性表中的数据元…...
【五.LangChain技术与应用】【2.LangChain虚拟环境搭建(下):环境优化与调试】
一、Docker化部署:别让你的环境成为薛定谔的猫 经历过"在我机器上能跑"惨案的老铁都懂,传统虚拟环境就像个黑盒子。去年我帮客户部署LangChain应用,因为glibc版本差了0.1,整个服务直接崩成烟花。从那天起,我所有项目都强制上Docker! Dockerfile生存指南: #…...
deepseek+mermaid【自动生成流程图】
成果: 第一步打开deepseek官网(或百度版(更快一点)): 百度AI搜索 - 办公学习一站解决 第二步,生成对应的Mermaid流程图: 丢给deepseek代码,或题目要求 生成mermaid代码 第三步将代码复制到me…...
Java实现大数据量导出报表
一、实现方式 在Java中,导出数据到Excel有多种方式,每种方式都有其优缺点,适用于不同的场景。以下是常见的几种方式及其特点: 1.1 Apache POI Apache POI 是 Java 中最流行的库,支持读写 Excel 文件(包括…...
在 Element Plus 的 <el-select> 组件中,如果需要将 <el-option> 的默认值设置为 null。 用于枚举传值
文章目录 引言轻松实现 `<el-option>` 的默认值为 `null`I 实现方式监听清空事件 【推荐】使用 v-model 绑定 null添加一个值为 null 的选项处理 null 值的显示引言 背景:接口签名规则要求空串参与,空对象不参与签名计算 // 空字符串“” 参与签名组串,null不参与签…...
Spring Boot 接口 JSON 序列化优化:忽略 Null 值的九种解决方案详解
一、针对特定接口null的处理: 方法一:使用 JsonInclude 注解 1.1 类级别:在接口返回的 DTO 类或字段 上添加 JsonInclude 注解,强制忽略 null 值: 类级别:所有字段为 null 时不返回 JsonInclude(Js…...
解码未来!安徽艾德未来智能科技有限公司荣获“GAS消费电子科创奖-产品创新奖”!
在2025年“GAS消费电子科创奖”评选中,安徽艾德未来智能科技有限公司提交的“讯飞AI会议耳机iFLYBUDS Pro 2”,在技术创新性、设计创新性、工艺创新性、智能化创新性及原创性五大维度均获得评委的高度认可,荣获“产品创新奖”。 这一殊荣不仅…...
