题解:P11638 Max,Mex

题解:P11638 Max,Mex

题目传送门

前置知识

i=1nai=a1+a2+a3+a4+a5++an

思路

本题中定义 max{S}S 中的最大值,mex{S}S 中最小没出现过的自然数。一次操作你可以选定一个 (i,j),满足 1i,jn 以及 ij,令 x=max{ai,aj}y=mex{ai,aj},那么 ai=xaj=y

subtask 1&2

  • 对于 subtask1 与 subtask2,直接输出 sum 即可。证明如下:
    • ai2 时,mex{ai,aj}=0,即 aj=0,对 i=1nai 没有贡献,所以不需要进行操作,在代码中进行特判即可。这样可拿到 [10,30] 分。

subtask 3&4

  • 对于 subtask3 与 subtask4,因为无特殊性质,所以需要判断关于 mex{ai,aj} 的所有情况,求出他们分别对 i=1nai 的贡献值并得出规律。

  • 我们会发现如下规律:

    • 对于一个操作,不论是 mex{ai,aj} 还是 max{ai,aj},只要 ai,aj2 时,根据 subtask 1&2 的结论,再进行操作显然对 i=1nai 没有贡献,所以我们只需统计数列中小于 2 的个数和大于等于 2 的数之和,并求出小于 2 的数的最大贡献值即可。
    • 因此,对于一组 ai,aj 有以下几种情况:
      • ai=0,aj=0 时,令 aj=mex{0,0}=1。此时 ai=0,aj=1
      • ai=0,aj=1 时,令 ai=max{0,1}=1aj=mex{0,1}=2。此时 ai=1,aj=2
      • ai=1,aj=2 时,令 ai=max{1,2}=2aj=mex{2,2}=0。此时 ai=2,aj=0。显然对 i=1nai 没有贡献,所以这个操作要舍去。
    • 综上,我们一共操作了三次,操作过后结果为 ai=1,aj=2,此时贡献值为 1+2=3
    • 因此,我们可以推导出 subtask 3&4 的通项公式。即对于 cnt0ans1,最后会有 cnt+ans1 个数操作成 2,剩下的一个数无法进行操作,即为 1。即对于小于等于 2ai,aj,最大贡献次数为:

      2×((cnt+ans)1)+1

    • 因此,subtask 3&4 的通项公式为:

      i=1nai+2×((cnt+ans)1)+1ans

      即:

      i=1n[ai0ai1]+2×cnt+ans1

关于hack数据

事实上,这是本代码的一个小 Bug。
n=1,ai=0 时,因为之前 cnt 记录 0 的个数时,cnt 便不会为 0,因此卡过了上文中的关于 subtask1 的部分。所以只要在这之前进行特判便没有问题了。

代码实现

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll cnt,ans,sum,n,a;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a;
		sum+=a;
		if(n==1){
			cout<<a;
			return 0;
		}
		if(a==0) cnt++;
		if(a==1) ans++;
	}
	if(cnt+ans==0) cout<<sum;
	else cout<<cnt*2+ans+sum-1;
	return 0;
}

本题思维难度略大,代码实现方面比较简单。

posted @   M1_Byte  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示