【Codeforces 1294D】MEX maximizing 题解(简单数学)

本文介绍了一个关于MEX最大化的算法题解,通过分析和优化数组元素,利用模运算和数组记录技巧,实现MEX值的最大化,复杂度为O(n)。

MEX maximizing 题解(简单数学)

MEX maximizing

这个题是一个比较简单的题目 稍作分析即可:
MEX maximizing题目描述
MEX maximizing题目描述
MEX maximizing题目描述
题意:
MEX:给出一个数组 求出除去这个数组中的元素之外的最小的非负整数

此时 在给定一个x 可以对数组中的任意一个元素加上或减去x(但是进行这个操作之后要保证这个元素仍然是一个非负整数) 使得这个数组的MEX最大

思路:
这个题想一想也没什么巧妙的方法 应该就是直接暴力
注意到MEX是 最小的非负整数 因此数组中的元素要将MEX“挤”上去的话 应该要保证元素不重复的情况下尽可能的小

而因为每一个数都可以与x进行加减操作 所以每一个数y都可以表示成:
y=k*x+t
那么对于输入的任意一个y而言 都可以用模x的余项t来表示
那么这时就可以开一个数组来记录 t 对应的 k 的大小

然后再开一个数组记录已经有元素占有的位置
就可以开始搜索这个MEX了
复杂度O(n)

#详见代码#

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxx=4e5+10;

int xnow[maxx],vis[maxx];
//  这个数组表示 当前这个的余项 到了几(因为输入的每一个数 都与x之间有一个余项)
//  输入的这个数 是什么类型  就只用看这个余项就可以了 
//  vis  就用来记录  有哪些数字是已经被占用了的 (因为 x最大也就maxx )
//  (输入的数的个数最多也就maxx)  所以y  的数值不用很是在意 
int q,x,y,k,point,t;

int main(){
	scanf("%d%d",&q,&x);
	point=0;
	
	for(int ii=1;ii<=q;ii++){
		scanf("%d",&y);
		
		k=y%x;
		t=k+x*xnow[k];
		if(t<=maxx){
			vis[t]=1;
			xnow[k]++;
		}
		
		for(;point<=maxx;point++){
			if(vis[point]==0){
				break;
			}
		}
		
		printf("%d\n",point);
	} 
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值