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

好数——前缀和思想(题目分享)

        今天我的舍友去参加“传智杯”广东省的省赛,跟我说了这样一道题,他说他想不出来怎么去优化代码,怎么做都是套用两层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),用于存储数组和前缀和。

通过这种设计,代码能够高效处理大规模数据,并满足题目对时间的要求。

相关文章:

好数——前缀和思想(题目分享)

今天我的舍友去参加“传智杯”广东省的省赛&#xff0c;跟我说了这样一道题&#xff0c;他说他想不出来怎么去优化代码&#xff0c;怎么做都是套用两层for循环超时&#xff0c;下面我就根据题意&#xff0c;使用前缀和的算法去优化一下思路&#xff0c;题目本身是不难的&#x…...

MWC 2025 | 移远通信大模型解决方案加速落地,引领服务机器人创新变革

随着人工智能、大模型等技术的蓬勃发展&#xff0c;生成式AI应用全面爆发。在此背景下&#xff0c;服务机器人作为大模型技术在端侧落地的关键场景&#xff0c;迎来了前所未有的发展机遇。 作为与用户直接交互的智能设备&#xff0c;服务机器人需要应对复杂场景下的感知、决策和…...

【大模型基础_毛玉仁】0.概述

更多内容&#xff1a;XiaoJ的知识星球 【大模型基础_毛玉仁】 系列文章参考 系列文章 【大模型基础_毛玉仁】0.概述 【大模型基础_毛玉仁】1.1 基于统计方法的语言模型 更新中。。。。。。 参考 书籍&#xff1a;大模型基础_完整版.pdf Github&#xff1a;https://github.co…...

ADB、Appium 和 大模型融合开展移动端自动化测试

将 ADB、Appium 和 大模型(如 GPT、LLM) 结合,可以显著提升移动端自动化测试的智能化水平和效率。以下是具体的实现思路和应用场景: 1. 核心组件的作用 ADB(Android Debug Bridge): 用于与 Android 设备通信,执行设备操作(如安装应用、获取日志、截图等)。Appium: 用…...

springboot425-基于SpringBoot的BUG管理系统(源码+数据库+纯前后端分离+部署讲解等)

&#x1f495;&#x1f495;作者&#xff1a; 爱笑学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…...

Ubuntu系统上部署Node.js项目的完整流程

以下是在Ubuntu系统上部署Node.js项目的完整流程&#xff0c;分为系统初始化、环境配置、项目部署三个部分&#xff1a; 一、系统初始化 & 环境准备 bash # 1. 更新系统软件包 sudo apt update && sudo apt upgrade -y# 2. 安装基础工具 sudo apt install -y buil…...

X Window---图形接口

摘抄自 鸟哥的linux私房菜 基础篇 第四版 有鉴于图形用户接口(Graphical User Interface, GUI) 的需求日益加重&#xff0c;在 1984 年由 MIT 与其他第三方首次发表了 X Window System &#xff0c;并且更在 1988 年成立了非营利性质的 XFree86 这个组织。所谓的XFree86 其实是…...

数据序列化协议 Protobuf 3 介绍(Go 语言)

Protobuf 3 入门 1. 什么是序列化&#xff1f; 1.1 概念 序列化&#xff08;Serialization 或 Marshalling&#xff09; 是指将数据结构或对象的状态转换成可存储或传输的格式。反向操作称为反序列化&#xff08;Deserialization 或 Unmarshalling&#xff09;&#xff0c;它…...

FineReport 操作注意

1.父单元格重复的时候&#xff0c;如何取消合并 效果如下&#xff1a; 只需要在单元格中&#xff0c;将数据设置为【列表】即可。 2.待定...

3D手眼标定转换详细实施步骤及原理概述

3D手眼标定转换详细实施步骤及原理概述 一、手眼标定的核心目标二、3D手眼标定的原理概述一、基本概念与坐标系定义**二、数学建模与方程推导****1. 坐标变换的齐次矩阵表示****2. 手眼标定方程推导** **三、方程求解方法****1. 分离旋转与平移****2. 旋转矩阵求解****3. 平移向…...

Verilog:SCCB控制器

目录 一、SCCB协议 &#xff08;1&#xff09;SCCB时序 &#xff08;2&#xff09;与I2C的区别 二、Verilog 实现 &#xff08;1&#xff09;设计要求 &#xff08;2&#xff09;设计要点 &#xff08;3&#xff09;模块完整代码 三、功能验证 &#xff08;1&#xff09;写…...

维度建模基础篇:从理论到核心组件解析

维度建模基础篇:从理论到核心组件解析 引言 在数据仓库与商业智能(BI)领域,维度建模​(Dimensional Modeling)作为一种经典的数据组织方法论,自Kimball提出以来,已成为构建高效分析型系统的核心范式1,2,3。其以业务需求为导向,通过事实表与维度表的组合,实现对复杂…...

与中国联通技术共建:通过obdiag分析OceanBase DDL中的报错场景

中国联通软件研究院&#xff08;简称联通软研院&#xff09;在全面评估与广泛调研后&#xff0c;在 2021年底决定采用OceanBase 作为基础&#xff0c;自研分布式数据库产品CUDB&#xff08;即China Unicom Database&#xff0c;中国联通数据库&#xff09;。目前&#xff0c;该…...

大数据与网络安全讲座

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 大数据的价值为大家公认。业界通常以4个“V”来概括大数据的基本特征——Volume(数据体量巨大)、Variety(数据类型繁多)、Value(价值密度低)、Velocity(处理速度快…...

AtCoder Beginner Contest 395 E

点我写题 题意&#xff1a;给个有向图&#xff0c;从1出发&#xff0c;每次可以走一条有向边&#xff0c;花费为1&#xff0c;也可以选择把全部有向边翻转&#xff0c;花费x&#xff0c;问到n的最小花费 思路&#xff1a;最短路dp&#xff0c;定义dis[i][0/1]表示走到i为止&…...

Linux进程管理6 - CFS调度

0、CFS调度器 CFS调度器使用完全公平调度算法。 完全公平调度算法引入虚拟运行时间的概念:虚拟运行时间 = 实际运行时间 * nice_0_weight / 进程的权重。完全公平调度算法使用红黑树把进程按虚拟运行时间从小到大排序,每次调度选择虚拟运行时间最小的进程。时间片 操作系统进…...

张驰咨询:用六西格玛重构动力电池行业的BOM成本逻辑

在动力电池行业&#xff0c;BOM&#xff08;物料清单&#xff09;成本每降低1%&#xff0c;都可能改写企业的利润曲线。某头部企业的三元锂电池BOM成本曾较行业标杆高出11%&#xff0c;单电芯利润率被压缩至3%的生死线。然而&#xff0c;通过张驰咨询的六西格玛方法论&#xff…...

pyside6学习专栏(九):在PySide6中使用PySide6.QtCharts绘制6种不同的图表的示例代码

PySide6的QtCharts类支持绘制各种型状的图表&#xff0c;如面积区域图、饼状图、折线图、直方图、线条曲线图、离散点图等&#xff0c;下面的代码是采用示例数据绘制这6种图表的示例代码,并可实现动画显示效果&#xff0c;实际使用时参照代码中示例数据的格式将实际数据替换即可…...

SpringBoot获取YAML配置文件中的属性值(二):使用Environment环境组件读取值

Spring Boot 使用 Properties 和 YAML 配置文件文件,系列文章: 《Spring使用@Value注解与@PropertySource注解加载配置文件》 《SpringBoot获取YAML配置文件中的属性值(一):使用@Value注解、@ConfigurationProperties注解》 《SpringBoot获取YAML配置文件中的属性值(二)…...

14天 -- Redis 的持久化机制有哪些?Redis 主从复制的实现原理是什么? Redis 数据过期后的删除策略是什么?

Redis 的持久化机制有哪些&#xff1f; Redis 是一种高性能的键值存储系统&#xff0c;主要用于缓存、消息队列等场景。为了防止数据丢失&#xff0c;Redis 提供了多种持久化机制&#xff0c;主要包括以下两种&#xff1a; 1. RDB&#xff08;Redis Database Backup&#xff…...

《深度学习实战》第10集:联邦学习与隐私保护

第10集&#xff1a;联邦学习与隐私保护 2025年3月4日更新了代码&#xff0c;补充了实例程序运行截图 和 如何提高模型准确率的方法 系统梳理 集集精彩 代码验证 保证实战 随着数据隐私问题日益受到关注&#xff0c;联邦学习&#xff08;Federated Learning&#xff09; 作为一…...

如何解决跨域请求的问题(CORS)?

文章目录 1. 引言2. 理解 CORS2.1 CORS 基本概念2.2 同源策略与跨域分类 3. CORS 的核心机制3.1 预检请求&#xff08;Preflight Request&#xff09;3.2 简单请求 4. 服务器端配置 CORS4.1 关键响应头4.2 Node.js (Express) 示例4.3 其他后端语言配置 5. 前端处理 CORS 请求5.…...

【数据结构】二叉树总结篇

遍历 递归 递归三部曲&#xff1a; 1.参数和返回值 2.终止条件 3.单层逻辑&#xff08;遍历顺序&#xff09; var preorderTraversal function(root) { // 第一种let res[];const dfsfunction(root){if(rootnull)return ;//先序遍历所以从父节点开始res.push(root.val);//递归…...

软考-数据库开发工程师-3.1-数据结构-线性结构

第3章内容比较多&#xff0c;内容考试分数占比较大&#xff0c;6分左右 线性表 1、线性表的定义 一个线性表是n个元素的有限序列(n≥0)&#xff0c;通常表示为(a1&#xff0c;a2, a3,…an). 2、线性表的顺序存储(顺序表) 是指用一组地址连续的存储单元依次存储线性表中的数据元…...

【五.LangChain技术与应用】【2.LangChain虚拟环境搭建(下):环境优化与调试】

一、Docker化部署:别让你的环境成为薛定谔的猫 经历过"在我机器上能跑"惨案的老铁都懂,传统虚拟环境就像个黑盒子。去年我帮客户部署LangChain应用,因为glibc版本差了0.1,整个服务直接崩成烟花。从那天起,我所有项目都强制上Docker! Dockerfile生存指南: #…...

deepseek+mermaid【自动生成流程图】

成果&#xff1a; 第一步打开deepseek官网(或百度版&#xff08;更快一点&#xff09;)&#xff1a; 百度AI搜索 - 办公学习一站解决 第二步&#xff0c;生成对应的Mermaid流程图&#xff1a; 丢给deepseek代码&#xff0c;或题目要求 生成mermaid代码 第三步将代码复制到me…...

Java实现大数据量导出报表

一、实现方式 在Java中&#xff0c;导出数据到Excel有多种方式&#xff0c;每种方式都有其优缺点&#xff0c;适用于不同的场景。以下是常见的几种方式及其特点&#xff1a; 1.1 Apache POI Apache POI 是 Java 中最流行的库&#xff0c;支持读写 Excel 文件&#xff08;包括…...

在 Element Plus 的 <el-select> 组件中,如果需要将 <el-option> 的默认值设置为 null。 用于枚举传值

文章目录 引言轻松实现 `<el-option>` 的默认值为 `null`I 实现方式监听清空事件 【推荐】使用 v-model 绑定 null添加一个值为 null 的选项处理 null 值的显示引言 背景:接口签名规则要求空串参与,空对象不参与签名计算 // 空字符串“” 参与签名组串,null不参与签…...

Spring Boot 接口 JSON 序列化优化:忽略 Null 值的九种解决方案详解

一、针对特定接口null的处理&#xff1a; 方法一&#xff1a;使用 JsonInclude 注解 1.1 类级别&#xff1a;在接口返回的 ‌DTO 类或字段‌ 上添加 JsonInclude 注解&#xff0c;强制忽略 null 值&#xff1a; 类级别&#xff1a;所有字段为 null 时不返回 JsonInclude(Js…...

解码未来!安徽艾德未来智能科技有限公司荣获“GAS消费电子科创奖-产品创新奖”!

在2025年“GAS消费电子科创奖”评选中&#xff0c;安徽艾德未来智能科技有限公司提交的“讯飞AI会议耳机iFLYBUDS Pro 2”&#xff0c;在技术创新性、设计创新性、工艺创新性、智能化创新性及原创性五大维度均获得评委的高度认可&#xff0c;荣获“产品创新奖”。 这一殊荣不仅…...