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

2023年信奥赛C++提高组csp-s初赛真题及答案解析(完善程序第2题)

2023年信奥赛C++提高组csp-s初赛真题及答案解析(完善程序第2题)

#### 第2题

(最大值之和)给定整数序列a 0 , ⋯ , a n − 1 a_0,⋯,a_{n−1}a0,,an1,求该序列所有非空连续子序列的最大值之和。上述参数满足1 ≤ n ≤ 10 5 和 1 ≤ a i ≤ 10 8 1≤n≤10^5和 1≤a_i≤10^81n1051ai108

一个序列的非空连续子序列可以用两个下标 l和 r(其中0≤l≤r<n)表示,对应的序列为a l , a l + 1 , ⋯ , a r a_l,a_{l+1},⋯,a_ral,al+1,,ar。两个非空连续子序列不同,当且仅当下标不同。

例如,当原序列为[ 1 , 2 , 1 , 2 ] [1,2,1,2][1,2,1,2]时,要计算子序列 [1]、[2]、[1]、[2]、[1,2]、[2,1]、[1,2]、[1,2,1]、[2,1,2]、[1,2,1,2] 的最大值之和,答案为 18。注意 [1,1] 和 [2,2]虽然是原序列的子序列,但不是连续子序列,所以不应该被计算。另外,注意其中有一些值相同的子序列,但由于他们在原序列中的下标不同,属于不同的非空连续子序列,所以会被分别计算。

解决该问题有许多算法,以下程序使用分治算法,时间复杂度 O(nlog⁡n)。

试补全程序。

#include<iostream>#include<algorithm>#include<vector>constintMAXN=100000;intn;inta[MAXN];longlongans;voidsolve(intl,intr){if(l+1==r){ans+=a[l];return;}intmid=(l+r)>>1;std::vector<int>pre(a+mid,a+r);for(inti=1;i<r-mid;++i);std::vector<longlong>sum(r-mid+1);for(inti=0;i<r-mid;++i)sum[i+1]=sum[i]+pre[i];for(inti=mid-1,j=mid,max=0;i>=l;--i){while(j<r&&)++j;max=std::max(max,a[i]);ans+=;ans+=;}solve(l,mid);solve(mid,r);}intmain(){std::cin>>n;for(inti=0;i<n;++i)std::cin>>a[i];;std::cout<<ans<<std::endl;return0;}
  1. ①处应填()

    A.pre[i] = std::max(pre[i - 1], a[i - 1])

    B.pre[i + 1] = std::max(pre[i],pre[i + 1])

    C.pre[i] = std::max(pre[i -1], a[i])

    D.pre[i] = std::max(pre[i], pre[i - 1])

  2. ②处应填()

    A.a[j] < max

    B.a[j] < a[i]

    C.pre[j - mid] < max

    D.pre[j - mid] > max

  3. ③处应填()

    A.(long long)(j - mid) * max

    B.(long long)(j - mid) * (i - 1) * max

    C.sum[j - mid]

    D.sum[j - mid] * (i - 1)

  4. ④处应填()

    A.(long long)(r - j) * max

    B.(long long)(r - j) * (mid - i) * max

    C.sum[r - mid] - sum[j - mid]

    D.(sum[r - mid] - sum[j - mid]) * (mid - i)

  5. ⑤处应填()

    A.solve(0,n)

    B.solve(0,n - 1)

    C.solve(1,n)

    D.solve(1,n - 1)

解题思路

该程序使用分治算法计算序列所有非空连续子序列的最大值之和。分治的核心思想是将区间[ l , r ) [l, r)[l,r)分成左右两半[ l , mid ) [l, \text{mid})[l,mid)[ mid , r ) [\text{mid}, r)[mid,r),递归计算左右内部的贡献,再计算跨越中点的子序列的贡献。

跨越中点贡献的计算

  • 预处理右半部分的前缀最大值数组pre及其前缀和数组sum
  • 对于每个左端点i ii(从mid − 1 \text{mid}-1mid1向左枚举),维护左半部分的最大值max \text{max}max,并利用双指针j jj将右端点分为两部分:
    1. 右端点j ∈ [ mid , j 0 ) j \in [\text{mid}, j_0)j[mid,j0):区间最大值由左半部分贡献,即max \text{max}max
    2. 右端点j ∈ [ j 0 , r ) j \in [j_0, r)j[j0,r):区间最大值由右半部分贡献,即pre [ j − mid ] \text{pre}[j-\text{mid}]pre[jmid]
  • 指针j jj的移动条件为:a [ j ] < a [ i ] a[j] < a[i]a[j]<a[i],即找到第一个a [ j ] ≥ a [ i ] a[j] \ge a[i]a[j]a[i]的位置。
答案及解析
  1. D:预处理pre为右半部分的前缀最大值。
  2. B:移动指针j jj的条件为a [ j ] < a [ i ] a[j] < a[i]a[j]<a[i]
  3. A:第一组贡献为( j − mid ) × max (\text{j} - \text{mid}) \times \text{max}(jmid)×max
  4. C:第二组贡献为sum [ r − mid ] − sum [ j − mid ] \text{sum}[r-\text{mid}] - \text{sum}[j-\text{mid}]sum[rmid]sum[jmid]
  5. A:初始调用为solve(0, n),表示整个区间[ 0 , n ) [0, n)[0,n)

专栏推荐:信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新)
https://blog.csdn.net/weixin_66461496/category_13125089.html


各种学习资料,助力大家一站式学习和提升!!!

#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"########## 一站式掌握信奥赛知识! ##########";cout<<"############# 冲刺信奥赛拿奖! #############";cout<<"###### 课程购买后永久学习,不受限制! ######";return0;}

1、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html

2、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

CSP信奥赛C++一等奖通关刷题题单及题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新)
https://blog.csdn.net/weixin_66461496/category_13125089.html

3、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转


GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html

4、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

· 文末祝福 ·

#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"跟着王老师一起学习信奥赛C++";cout<<" 成就更好的自己! ";cout<<" csp信奥赛一等奖属于你! ";return0;}
http://www.jsqmd.com/news/364803/

相关文章:

  • 手机编辑公众号模板免费套用,10款主流手机版公众号排版工具推荐测评 - peipei33
  • 搞定模型服务化部署中的动态批处理
  • Libvio.link反爬机制深度剖析
  • chat2db邀请码A66666
  • STM32WLE5 + MM8108-MF15457 组合模组设计方案(低功耗+高速通信)
  • C++构造函数与析构函数:对象生命周期的守护者
  • FPGA神经网络功耗稳定性监控的优化策略与实战指南
  • 流数据测试:LSTM-Kafka在消息积压阈值预测的监控插件‌
  • 从零理解卷积神经网络(CNN):比全连接强在哪?
  • 对象和类(类的构造函数和析构函数)
  • 卷积神经网络(整体结构)
  • 颠覆性技术变革:AI驱动无代码测试新范式
  • 【prompt】- mcp开发专家
  • 轮廓线 插头 DP
  • PostgreSQL复制的监控
  • C++变量的基础使用
  • 【完整源码+数据集+部署教程】交通标线车道线分割系统源码&数据集分享 [yolov8-seg-C2f-EMSC&yolov8-seg-SPPF-LSKA等50+全套改进创新点发刊_一键训练教程_We
  • IoT电子价签:打造智能化商超秋冬新品促销新体验 - 指南
  • pc(mac/win)端app 能基于webkit 打包发布
  • 【完整源码+数据集+部署教程】航拍区域图像分割系统源码&数据集分享 [yolov8-seg-C2f-DAttention&yolov8-seg-HGNetV2等50+全套改进创新点发刊_一键训练教程
  • 【完整源码+数据集+部署教程】工图机械零件特征图像分割系统源码&数据集分享 [yolov8-seg-LAWDS&yolov8-seg-RevCol等50+全套改进创新点发刊_一键训练教程_Web前端
  • 洛谷 P1160:队列安排 ← 数组模拟
  • 小白版详解:剪枝怎么评好坏?怎么判断该剪谁?
  • 2026年北京VIP陪诊公司权威测评,高品质服务机构精选 - 品牌鉴赏师
  • 三种剪枝算法流程
  • 【含文档+PPT+源码】基于微信小程序的驾考在线学习与测试系统的设计与实现
  • 2026.02.10
  • 【Matlab】MATLAB 图形标注教程:title、xlabel、ylabel 用法详解与实战
  • 小鼠CD185抗体如何助力CXCR5靶向ADC药物的研发与机制探索?
  • Node.js 编程实战:路径模块(path)详解 - 教程