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

【C++贪心】P8411 「SvR-1」Problem|普及

本文涉及知识点

C++贪心

「SvR-1」Problem

题目背景

小 L 打颓被 nodgd 发现,于是他开始做题了。

题目描述

他的 DS 非常菜,于是他把一共 n n n 道 DS 题加到了自己的计划题单里,其中第 i i i 道题的有趣程度为 a i a_i ai

由于他并不精通 DS,他发现他在做一些题目之前需要先做另一些题目。这样的关系共有 n − 1 n - 1 n1 组,他还发现每道题都出现在了这些关系中且没有重复。

他发现 ∀ 2 ≤ i ≤ n \forall 2 \leq i \leq n ∀2in,第 i i i 题和第 f a i fa_i fai 题间存在上文所述的关系,且 1 ≤ f a i < i 1 \leq fa_i < i 1fai<i他必须先做第 f a i fa_i fai 题后才能做第 i i i

他发现,如果他在做一道题之前高兴程度为 k k k,则他做完第 i i i 题后,他的高兴程度便会变为 min ⁡ ( k , a i ) \min(k, a_i) min(k,ai)他做题前的高兴程度为无穷大

他想问你在必须先做第 1 1 1 题且不能重复做某一道题的情况下,他在做题的全过程中每做完一道题后高兴程度之和的最大值

输入格式

第一行,两个整数 n , s e e d n, seed n,seed

由于输入量较大,我们采用如下方式生成 a i , f a i a_i, fa_i ai,fai

C++:

typedef unsigned int uint;inline uint get_next(uint &seed){seed ^= seed << 13;seed ^= seed >> 17;seed ^= seed << 5;return seed;
}int main(){// ...for (int i = 1; i <= n; i++){a[i] = get_next(seed);}for (int i = 2; i <= n; i++){fa[i] = get_next(seed) % (i - 1) + 1;}// ...return 0;
}

使用其他语言的选手请参考「说明/提示」中的「伪代码参考」。

输出格式

一行,一个整数,表示所求的值。

样例 #1

样例输入 #1

6 114514

样例输出 #1

14907285111

提示

样例 #1 解释

在该组样例中 a = [ 3398922311 , 3077554952 , 2933028207 , 4018360144 , 1263042788 , 835814542 ] a = [3398922311, 3077554952, 2933028207, 4018360144, 1263042788, 835814542] a=[3398922311,3077554952,2933028207,4018360144,1263042788,835814542] f a 2 = f a 3 = f a 4 = 1 fa_2 = fa_3 = fa_4 = 1 fa2=fa3=fa4=1 f a 5 = f a 6 = 2 fa_5 = fa_6 = 2 fa5=fa6=2

最优方案之一:依次做第 1 , 4 , 2 , 3 , 5 , 6 1, 4, 2, 3, 5, 6 1,4,2,3,5,6 题,最大值为 3398922311 + 3398922311 + 3077554952 + 2933028207 + 1263042788 + 835814542 = 14907285111 3398922311 + 3398922311 + 3077554952 + 2933028207 + 1263042788 + 835814542 = 14907285111 3398922311+3398922311+3077554952+2933028207+1263042788+835814542=14907285111

伪代码参考

KaTeX parse error: Expected a control sequence at position 6: \def{̲\b}#1{ \textbf{…

其中 left ( x , d ) \text{left}(x,d) left(x,d) right ( x , d ) \text{right}(x,d) right(x,d) 分别表示将 x x x 左移或右移 d d d 位。

数据规模与约定

本题自动开启捆绑测试和 O2 优化。
Subtask n ≤ 分值 1 10 10 2 1 0 4 20 3 1 0 6 20 4 无特殊限制 50 \newcommand{\arraystretch}{1.5} \begin{array}{c|c|c}\hline\hline \textbf{Subtask} & \bm{n \leq} & \textbf{分值} \\\hline \textsf{1} & 10 & 10 \\\hline \textsf{2} & 10^4 & 20 \\\hline \textsf{3} & 10^6 & 20 \\\hline \textsf{4} & \text{无特殊限制} & 50 \\\hline\hline \end{array} Subtask1234n10104106无特殊限制分值10202050

对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 1 0 7 1 \leq n \leq 10^7 1n107 0 ≤ s e e d < 2 32 0 \leq seed < 2^{32} 0seed<232

贪心之临项交换

某步可以选择ai,或aj。选择大的。更新这两项目,对之前和之后的项目,无影响。即相邻两项ai,aj。以下两种情况不会同时存在:一,ai不是aj的前置。二,ai < aj。
否则更换之:
先选择ai,则这两项之和是:min(k,ai)+min(k,ai,aj)
先选择aj,则这两项之和是:min(k,aj)+min(k,ai,aj)
故先选择ai劣于先选择aj。
fa转为后序节点。每次都选择最大。
用优先队列时间复杂度是: O(nlogn) 第四个子测试过不了。

代码

#include <iostream>
#include <sstream>
#include <vector>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<string>
#include<algorithm>
#include<functional>
#include<queue>
#include <stack>
#include<iomanip>
#include<numeric>
#include <math.h>
#include <climits>#include <bitset>
using namespace std;template<class T = int>
vector<T> Read(int n,const char* pFormat = "%d") {vector<T> ret;T d ;while (n--) {scanf(pFormat, &d);ret.emplace_back(d);}return ret;
}template<class T = int>
vector<T> Read( const char* pFormat = "%d") {int n;scanf("%d", &n);vector<T> ret;T d;while (n--) {scanf(pFormat, &d);ret.emplace_back(d);}return ret;
}string ReadChar(int n) {string str;char ch;while (n--) {do{scanf("%c", &ch);} while (('\n' == ch));str += ch;}return str;
}typedef unsigned int uint;class Solution {
public:long long MaxS(const int N, uint seed) {vector<uint> a(N + 1);vector<vector<int>> vNext(N + 1);// ...for (int i = 1; i <= N; i++) {a[i] = get_next(seed);}for (int i = 2; i <= N; i++) {const int par = get_next(seed) % (i - 1) + 1;vNext[par].emplace_back(i);}priority_queue<pair<uint, int>> heap;heap.emplace(a[1], 1);long long ans = 0;uint cur = UINT_MAX;while (heap.size()) {const auto [curv, i] = heap.top();heap.pop();cur = min(cur, curv);ans += cur;for (const auto& next : vNext[i]) {heap.emplace(a[next], next);}}return ans;}inline uint get_next(uint& seed) {seed ^= seed << 13;seed ^= seed >> 17;seed ^= seed << 5;return seed;}};int main() {
#ifdef _DEBUGfreopen("a.in", "r", stdin);
#endif // DEBUGint n;uint seed;scanf("%d%u", &n,&seed);auto res = Solution().MaxS(n,seed);cout << res << std::endl;return 0;
}

本题

父节点 一定 < 子节点。
所以从小到大处理节点时,所有的祖先节点一定已经处理,故:a[i] = min(a[父节点],a[i])
处理过程:选择最大值,相同值按父子关系选取。
然后次大值…
答案即是 ∑ \sum a。

代码

核心代码

class Solution {public:long long MaxS(const int N, uint seed) {vector<uint> a(N + 1);vector<vector<int>> vNext(N + 1);// ...for (int i = 1; i <= N; i++) {a[i] = get_next(seed);}for (int i = 2; i <= N; i++) {const int par = get_next(seed) % (i - 1) + 1;a[i] = min(a[i], a[par]);}				return accumulate(a.begin(),a.end(),0ll);}inline uint get_next(uint& seed) {seed ^= seed << 13;seed ^= seed >> 17;seed ^= seed << 5;return seed;}};

单元测试

	TEST_METHOD(TestMethod11){			auto res = Solution().MaxS(6 ,114514);AssertEx(14907285111ll, res);}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

相关文章:

  • 亚马逊云服务器性能深度优化方案(2025版)
  • Aws S3上传优化
  • Spring MVC @RequestHeader 注解怎么用?
  • 第5篇:EggJS中间件开发与实战应用
  • 【学习笔记】深入理解Java虚拟机学习笔记——第2章 Java内存区域与内存溢出异常
  • JavaScript性能优化实战之运行时性能优化
  • gRPC学习笔记记录以及整合gin开发
  • 云原生后端:构建高效、可扩展的现代后端架构
  • JVM——JVM 是如何执行方法调用的?
  • NFS 快速开始
  • React的patch流程
  • MySQL基本查询(二)
  • Python清空Word段落样式的方法
  • 【iOS】类与对象底层探索
  • 2025年- H20-Lc128-240. 搜索二维矩阵 II(矩阵)---java版
  • Qt 项目代码解释(4)
  • 【点对点协议(PPP)全解析】从原理到工程实践
  • PostgreSQL:pgJDBC 下载和安装
  • DeepSeek玄学指令大全
  • Redis TLS 加密对性能的影响分析
  • 韩国代总统、国务总理韩德洙宣布辞职
  • 小核酸药物企业瑞博生物递表港交所,去年亏损2.81亿元
  • 2025年“投资新余•上海行”钢铁产业“双招双引”推介会成功举行
  • 石家庄:城市更新,生活向美
  • 深一度|“凑合过”的利物浦,英超第二冠只求性价比
  • 首映|马丽:真想抱抱臧姑娘,对她说辛苦了