CSP模拟 取模

news/2024/9/20 6:44:07/文章来源:https://www.cnblogs.com/SkyNet-PKN/p/18405404

最近开始写 CSP 模拟的题,实际上考的题一点也不 CSP

题意

有一个长度为 \(n\) 的序列 \(A\)\(0\leq A_i<k\),你可以每次选取一个区间,将区间内所有元素 \(+1\),然后将区间内所有元素对 \(k\) 取模。问最少几次操作可以把序列中所有元素都变为 \(0\)

思路

假设现在有一个数列 \([2,3,1,0,3,2]\)\(k=4\),我们考虑如何将它变为 \(0\)

发现每次操作后都要模 \(k\) 的限制非常烦,因此我们做一个转化,每次操作直接加,而“区间内所有元素等于 \(0\)” 转化为了 “区间内所有元素\(\bmod k=0\) ”。

以上图为例,最优的方案为 \((1,7),(2,6),(3,5),(4,4),(4,4)\),共五步,我们把表示“增加值”的序列 \(B\) 用橙色表示。

如果把整张图“倒过来”,如下图,我们惊喜地发现这是一个经典问题,求多少次区间加 \(1\) 能覆盖代表 \(B\) 的橙色部分。很显然,操作次数即为 \(B\) 的差分数组 \(B^d\) 中的 \(>0\) 的数之和。

并且我们发现 \(B_i=(k-A_i)+ck\),且 \(c\) 的取值只可能为 \(0\)\(1\) 时才优,为什么?因为考虑初始时差分数组 \(B^d\) 中所有元素绝对值一定是 \(<k\) 的,那么 \(B_i\) 加一次 \(k\) 体现在 \(B^d\) 上便为 \(B^d_i+k,B^d_{i+1}-k\),可以发现此时 \(B^d_i\) 必为正数且 \(B^d_{i+1}\) 必为负数,那么再加由于 \(B^d_{i+1}\) 只会越来越负不计入答案,而 \(B^d_i\) 为正且越来越大,\(B^d\) 的正数和只会更大。

因此我们考虑找到最优的给 \(B_i\)\(k\) 的方案,根据差分数组的性质,若 \(B\) 上有连续的一段区间 \([l,r-1]\) 都被加上 \(k\),则反映到 \(B^d\) 上为 \(B^d_l+k,B^d_r-k\),此时 \(B^d_l\) 必为正数,\(B^d_r\) 必为负数,假设原先 \(B^d_r\) 为正数,那么这个操作对答案的贡献为原先的 \(B^d_r\) 减去现在的 \(B^d_l\)。听到这 solution 大概已经浮出水面了:即遍历差分数组 \(B^d\),对于每个大于 \(0\)\(B^d_i\),找它前面最小的 \(B^d_j\) 判断操作后能不能使得答案变得更小,贪心即可。

注意操作后 \(B^d_i\) 将会变成负数,它也可以和后面的其他 \(B^d_t>0\) 进行一次操作。这有点类似反悔贪心的思想:对于 \(j<i<t\)\(j\)\(i\) 操作,\(i\) 再和 \(t\) 操作实际上等价于 \(j\)\(t\) 操作,\(i\) 就被“反悔”掉了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int MAXN=1e7+5;
int n=0,k,a[MAXN],b[MAXN];
string num;
priority_queue<pii,vector<pii>,greater<pii>>pq;
int main(){freopen("modulo.in","r",stdin);freopen("modulo.out","w",stdout);ios::sync_with_stdio(false);cin>>k>>num;a[++n]=num[0]-'0';for(int i=1;i<num.size();i++){if(num[i]!=num[i-1])a[++n]=num[i]-'0';}for(int i=1;i<=n;i++){if(a[i]!=0) a[i]=k-a[i];}for(int i=1;i<=n;i++){b[i]=a[i]-a[i-1];}for(int i=1;i<=n;i++){if(b[i]<0) pq.push(make_pair(b[i],i));else if(b[i]>0){if(pq.empty()) continue;int id=pq.top().second;if(b[id]+k<b[i]){pq.pop();b[id]+=k;b[i]-=k;pq.push(make_pair(b[i],i));}}}int ans=0;for(int i=1;i<=n;i++){if(b[i]>0) ans+=b[i];}cout<<ans<<endl;return 0;
}

后记

CF有道题有点类似,实际上还要简单一点,CF1852C。

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

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

相关文章

爬虫案例2-爬取视频的三种方式之一:requests篇(1)

@目录前言爬虫步骤确定网址,发送请求获取响应数据对响应数据进行解析保存数据完整源码共勉博客 前言 本文写了一个爬取视频的案例,使用requests库爬取了好看视频的视频,并进行保存到本地。后续也会更新selenium篇和DrissionPage篇。当然,爬取图片肯定不止这三种方法,还有基…

支持向量机模型 0基础小白也能懂(附代码)

本篇我们要讲解的模型是大名鼎鼎的支持向量机 SVM,这是曾经在机器学习界有着近乎「垄断」地位的模型,影响力持续了好多年。直至今日,即使深度学习神经网络的影响力逐渐增强,但 SVM 在中小型数据集上依旧有着可以和神经网络抗衡的极好效果和模型鲁棒性。支持向量机模型 0基础…

LeetCode题集-3 - 无重复字符的最长子串

本文讨论了给定字符串找最长无重复字符子串的三种解法:双指针法、双指针+哈希法、双指针+数组法。其中,双指针+数组法因ASCII码特性效率最高,基准测试表明其优于哈希法。题目:给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。我们先来好好理解题目,示例1…

2-5Java多态

Java 多态 多态是同一个行为具有多个不同表现形式或形态的能力。 多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:多态性是对象多种表现形式的体现。 现实中,比如我们按下 F1 键这个动作:如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档; 如果当前在 Wor…

【VMware by Broadcom】Fusion 产品下载汇总

Fusion 产品下载汇总(百度网盘)-『2024年9月9日更新』Fusion 产品版本 百度网盘VMware-Fusion-1.0.0-51348.dmg 链接:https://pan.baidu.com/s/1C8Qkr6nwV5rKrhpsv2JJ_A?pwd=t0kjVMware-Fusion-1.1.0-62573.dmgVMware-Fusion-1.1.1-72241.dmgVMware-Fusion-1.1.2-87978.dmg…

C#/.NET/.NET Core技术前沿周刊 | 第 4 期(2024年9.1-9.8)

前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。欢迎投稿,推荐或自荐优质文章/项目/学习资源等。…

51nod 1051 最大子矩阵和

51nod 1051 最大子矩阵和 可以用前缀和容斥优化到 \(O(n^4)\),但是不够进行如下图操作:将每一列的数值都压缩到一维的数组上,就转换为求最大字段和问题,时间复杂度 \(O(n^3)\)。 看看代码就知道了。 #include <bits/stdc++.h> using namespace std; #define ll long …

VS中如何将本地代码上传到码云仓库

VS中如何将本地代码上传到码云仓库 方式一:点击“添加到源代码管理”VS底部栏点击“添加到源代码管理”,并选择“Git”选项在弹出窗口中,选择“其他→现有远程”选项,在右侧区域找到“远程URL”输入框,输入Gitee仓库地址,然后点击“创建并推送”按钮。此时项目目录会多出…

Linux下网络丢包故障定位

转载: 云网络丢包故障定位全景指南 硬件网卡丢包 Ring Buffer溢出如图所示,物理介质上的数据帧到达后首先由NIC(网络适配器)读取,写入设备内部缓冲区 Ring Buffer中,再由中断处理程序触发 Softirq 从中消费,Ring Buffer 的大小因网卡设备而异。当网络数据包到达(生产)…

第一次个人编程作业

github地址这个作业属于哪个课程 计科22级12班这个作业要求在哪里 作业要求链接这个作业的目标 遍历论文查重并封装成可执行文件,学习PSP和commit规范,学习测试和评估代码一、设计思路 文件结构:程序流程:实现逻辑:查找资料发现比较简单的实现是通过计算余弦向量来实现重复…

echart map图标切换多选,单选,默认选中

需求是echart默认地图选中之前的去过的城市,一开始多选,后面点击为单选const option = {tooltip: {trigger: item,formatter: {b}},series: [{type: map,roam : true,//是否开启缩放和平移zoom : 1,//当前视角缩放比例selectedMode: multiple, // 只允许单选// 设置为一张完整…

CH58x/CH59x/CH57x RF_PHY(2.4g)切换Channel发送接收

前言:在做某些应用的时候可能需要我们发送或者接收时切换对应的channel。 此次完成测试的平台在WCH的CH592F上完成的。 在工作发送过程中切换37、38、39三个信道进行轮询发送。具体需要使用最关键的函数是:RF_SetChannel 实现代码如下:if(events & channl_37_tx_evt){RF…