Codeforces Round 1011 (Div. 2)

news/2025/3/23 1:10:04/文章来源:https://www.cnblogs.com/maburb/p/18787408

A. Serval and String Theory

题意:给你一个字符串\(s\),你每次可以交换其中两个位置的字符,最多操作\(k\)次,求可不可以使得\(s\)的字典序比\(res(s)\)小。其中\(rev(s)\)\(s\)翻转后的的字符串。

首先如果\(s\)的所有位置都是一样的,无解。
否则如果\(s[n]\)都是所有字符里最小的,那么把\(s[n]\)换成最大的字符,否则\(s[1]\)是最小的,无需操作,都不是最小的,把\(s[1]\)换成最小的就行。
于是我们最多需要一次操作。注意如果\(s < rev(s)\)那么我们也不需要操作。

点击查看代码
void solve() {int n, k;std::cin >> n >> k;std::string s;std::cin >> s;std::string t = s;std::reverse(t.begin(), t.end());std::set<char> set;for (auto & c : s) {set.insert(c);}if (set.size() == 1 || (t <= s && k == 0)) {std::cout << "NO\n";} else {std::cout << "YES\n";}
}

B. Serval and Final MEX

题意:给你一个数组,每次选一个区间,把这个区间的都删掉,然后插入它们的\(mex\)。要让最后只剩下一个\(0\)。求操作方案。

分类讨论。
首先找到最左边和最右边的\(0\),记为\(l, r\)
如果没有\(0\),那么直接一次操作\([1, n]\)就行。
否则如果\(l=r\),如果\(l=1\)则需要先操作\([l, n - 1]\),然后剩下就没有\(0\)了。否则如果\(l=n\),先操作\([2, n]\),剩下就没有\(0\)了。
如果\(l!=r\)也是类似上面的讨论,特判有没有\(0\)在边界的情况。

点击查看代码
void solve() {int n;std::cin >> n;std::vector<int> a(n);for (int i = 0; i < n; ++ i) {std::cin >> a[i];}int l = 0, r = n - 1;while (l < r && a[l] != 0) {++ l;}while (l < r && a[r] != 0) {-- r;}if (a[l] != 0) {std::cout << 1 << "\n";std::cout << 1 << " " << n << "\n";} else if (l == r) {std::cout << 2 << "\n";if (l == 0) {std::cout << 1 << " " << n - 1 << "\n";std::cout << 1 << " " << 2 << "\n";} else if (l == n - 1) {std::cout << 2 << " " << n << "\n";std::cout << 1 << " " << 2 << "\n";} else {std::cout << 2 << " " << n << "\n";std::cout << 1 << " " << 2 << "\n";}} else {if (l == 0 && r == n - 1) {std::cout << 3 << "\n";std::cout << 3 << " " << n << "\n";std::cout << 1 << " " << 2 << "\n";std::cout << 1 << " " << 2 << "\n";} else if (l == 0) {std::cout << 2 << "\n";std::cout << 1 << " " << n - 1 << "\n";std::cout << 1 << " " << 2 << "\n";} else if (r == n - 1) {std::cout << 2 << "\n";std::cout << 2 << " " << n << "\n";std::cout << 1 << " " << 2 << "\n";} else {std::cout << 3 << "\n";std::cout << r + 1 << " " << n << "\n";std::cout << 1 << " " << r << "\n";std::cout << 1 << " " << 2 << "\n";}}
}

C. Serval and The Formula

题意:给你\(x, y\),找一个\(k\),使得\((x + k) + (y + k) = (x + k) \oplus (y + k)\)

首先\(a + b \geq a \oplus b\),大于的情况是\(a+b\)产生了进位。等于的情况则是没有进位,如果没有进位,那么\(a, b\)每一位都不同时为\(1\)

那么显然\(x=y\)是无解的,那么如果\(x\ne y\)我们可以求一个\(s\)使得\(s\)是第一个大于等于\(\max(x, y)\)的数。那么\(k\)可以等于\(s - \max(x, y)\)。假设\(x > y\),那么\(x + k\)后变成了\(s\)\(y + k<s\),而\(s\)除了最高位其它位都是\(0\),所以符合条件。

点击查看代码
void solve() {i64 x, y;std::cin >> x >> y;if (x == y) {std::cout << -1 << "\n";return;}i64 n = std::max(x, y);i64 s = 1;while (s < n) {s <<= 1;}i64 k = s - n;std::cout << k << "\n";
}

D. Serval and Kaitenzushi Buffet

题意:有\(n\)个物品,每个物品有一个价值,你按顺序操作,每次选择拿走一个物品,或者消化之前拿过的某个物品,或者上面都不做。每个物品需要\(k\)次才能消化,最后你要恰好消耗拿过的所有物品,求最大价值。

如果我们选择了\(m\)个物品,那么我们总共需要\(m \times (k + 1)\)次操作。但并不是操作数满足就合法,因为我们需要每个后缀都能满足,也就是说,只拿最后一个物品可以满足条件,只拿最后两个物品可以满足条件... 那么我们可以从后往前枚举,最后一个我们只能在\([1, n - k]\)里拿,最后两个我们只可以在\([1, n - 2k - 1]\)里拿... 那么我们把数组分成\(\lfloor \frac{n}{k+1} \rfloor\)段,从后往前找每一段的最右边可以拿到的位置\(i\),那么这一段可以在\([i - k, i]\)拿一个数。我们还需要考虑用当前区间的某个数换之前的数,因为我们用更前面的数换后面的数肯定也合法。那么算法如下:
我们用线段树维护区间最大值。如何从后往前枚举,用一个\(multiset\)存已经拿过的数,每次操作一个新区间,如果这个区间的最大值比之前拿到过的数最小值大,我们就不断更换,每次更换后把最大值的位置修改成\(0\)
总共有\(\lfloor \frac{n}{k+1} \rfloor\)个区间,每个区间最多操作\(k + 1\)次,那么时间复杂度就是线段树的复杂度,是\(nlogn\)

点击查看代码
#define ls (u << 1)
#define rs (u << 1 | 1)
#define umid (tr[u].l + tr[u].r >> 1)template <class Info>
struct Node {int l, r;Info info;
};template <class Info>
struct SegmentTree {std::vector<Node<Info> > tr;SegmentTree(int _n) {init(_n);}SegmentTree(std::vector<Info> & a) {init(a);}void init(int _n) {tr.assign(_n << 2, {});build(0, _n - 1);}void init(std::vector<Info> & a) {int _n = (int)a.size();tr.assign(_n << 2, {});build(0, _n - 1, a);}void pushup(int u) {tr[u].info = tr[ls].info + tr[rs].info;}void build(int l, int r, int u = 1) {tr[u] = {l, r, {}};if (l == r) {return;}int mid = l + r >> 1;build(l, mid, ls); build(mid + 1, r, rs);}void build(int l, int r, std::vector<Info> & a, int u = 1) {tr[u] = {l, r, {}};if (l == r) {tr[u].info = a[l];return;}int mid = l + r >> 1;build(l, mid, a, ls); build(mid + 1, r, a, rs);pushup(u);}void modify(int p, Info add, int u = 1) {if (tr[u].l == tr[u].r) {tr[u].info = add;return;}int mid = umid;if (p <= mid) {modify(p, add, ls);} else {modify(p, add, rs);}pushup(u);}Info query(int l, int r, int u = 1) {if (l <= tr[u].l && tr[u].r <= r) {return tr[u].info;}int mid = umid;if (r <= mid) {return query(l, r, ls);}  else if (l > mid) {return query(l, r, rs);}return query(l, r, ls) + query(l, r, rs);}
};struct Info {	i64 max, p;
};Info operator + (const Info & a, const Info & b) {Info res{};if (a.max >= b.max) {res = a;} else {res = b;}return res;
}void solve() {int n, k;std::cin >> n >> k;std::vector<i64> a(n);std::vector<Info> info(n);for (int i = 0; i < n; ++ i) {std::cin >> a[i];info[i] = {a[i], i};}SegmentTree<Info> tr(info);i64 ans = 0, sum = 0;std::multiset<i64> s;for (int i = n - 1 - k; i >= 0; i -= k + 1) {ans = std::max(ans, sum + tr.query(0, i).max);int l = std::max(0, i - k);s.insert(0);while (tr.query(l, i).max > *s.begin()) {sum -= *s.begin();s.erase(s.begin());auto v = tr.query(l, i);sum += v.max;tr.modify(v.p, Info{0, v.p}, true);s.insert(v.max);}ans = std::max(ans, sum);}std::cout << ans << "\n";
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/903715.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CodeForces训练记录】Codeforces Round 1011 (Div. 2)

训练情况赛后反思 B题因为分讨的问题WA了一发,异或还是不大会做 A题 猜猜题,显然对于字符串全部都是一个字母的,无论怎么换字典序都不可能更小,对于其他情况因为可以选择两个字母互换,我们容易观察到对于某一个字符串一定存在一种换法能让字典序更小(无非就是换头或者换尾…

集美大学课程实验报告-实验3:栈、队列与递归

集美大学课程实验报告-实验3:栈、队列与递归项目名称 内容课程名称 数据结构班级 网安2413指导教师 郑如滨学生姓名 林沁茹学号 202421336067实验项目名称 实验3:栈、队列与递归上机实践日期上机实践时间 2学时一、目的(本次实验所涉及并要求掌握的知识点) 以下内容请根据实…

2025-03-22 闲话

2025-03-22 闲话有些闲话是纪实的,它们可能只是平淡的文字。它们可能没有感受,不带思考。你看不到装饰,只有琐碎、补也补不到自圆其说的细节。柴米油盐大抵是这样的。 来北京独居后的生活着实安逸。每天执行一个蛮正常的作息,保证三顿饮食、偶尔晚上和网友去搓搓夜宵。睡觉…

3.22 三重积分计算方法

三重积分的实际意义:计算一个立体的质量(可以) 1 投影法(先一后二)(一个土豆切成土豆丝,最后再累加Dxy平面) 一个立体图形可以看成是两个曲面拼接而成,z=(x,y)可表示一个曲面假设x和y都是确定的,然后就累加z,最后再算面积分 先假设有一条竖线,注意竖线是从哪里进入…

15.数组

数组C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。 数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。数组中的特定元素可以通过索引访问,第一个索引值为 0。声明数组在 C 中要声明一个数组,需要指定元素的类型和元素的数量 下…

逆向中简单的shellcode

做题时遇到了,简单记录一下 一,介绍: shellcode分为广义和狭义,狭义指的仅仅是通过命令行shell攻击靶机,并取得控制权的代码,广义的指能完成类似任务的代码,通常是汇编/机器码。 不过这里是RE,不是PWN,所以不会有靶机,那么在下文指的是广义的shellcode,注入程序,控…

linux一些好用命令:w,fuer,getfacl,usermod,chmod

一.命令 w w 是显示用户登录时间、空闲时间、当前执行的命令等。 2.示例 pst/* : 这是ssh登录 tty: 这是直接本地登录(ctrl+alt +F* 都可以) 这个是没本地登录显示的进程 二. 命令 fuser fuser 是一个可以查看使用此文件的进程号。 1.一般使用 fuser -a /path/to/filename…

Aligning the Objective of LLM-based Program Repair 论文笔记

介绍 (1) 发表 2025-02 ICSE24 (2) 挑战当前方法的推理目标与 LLM 的训练目标没有对齐。现有 LLM-based 方法通常采用 MLM 的方式预测修复代码(然而尽管模型参数被增大百倍但修复结果甚至没有翻一番,这与其他任务的明确可伸缩性形成对比)。因此本文假设在训练中 <masked,…

监狱智能视频分析告警系统解决方案

监狱智能视频分析告警系统解决方案能够精准监测到静坐不动、离床、攀高、独处等行为。例如,当一名囚犯长时间静坐不动时,监狱智能视频分析告警系统解决方案会自动识别并发出预警,以便管理人员及时了解情况,防止囚犯出现自伤、自残等危险行为。在洗手间场景中,系统对入厕超…

昆明理工大学最新《现代材料测试技术》复试真题及答案

-材料测试 昆工材料物理与化学、材料学、材料表征与分析、材料工程、F001现代材料测试技术、864材料科学基础、昆明理工大学材料调剂

RTT 全志D1s跑tina linux

刚毕业那会抽奖抽了一块RTT的D1S开发板,看了一下打印log就放下吃灰了。跑RT-thread的感觉折腾起来太麻烦了就让他吃灰了。最近手头有一块屏幕和一个2欧的小喇叭打算驱动一下。 正好这块板子也出来好多年了。玩一玩。首先我找到了百问网的哪吒开发板他也是D1S的,直接把他的SDK…

COMSOL 基础学习笔记

设置网格 软件通过计算网格顶点的数值,推算其他位置的数值。 行函数:移动的波。 二次行函数(除网格顶点外还计算两定点连线中心的值):网格最大长度 \(≤\frac{λ}{6}\) 一次行函数:网格最大长度 \(≤\frac{λ}{12}\) 修改方式: