题意描述
Recall that MEX of an array is a minimum non-negative integer that does not belong to the array. Examples:
for the array [0,0,1,0,2] MEX equals to 3 because numbers 0,1 and 2 are presented in the array and 3 is the minimum non-negative integer not presented in the array; for the array [1,2,3,4] MEX equals to 0 because 0 is the minimum non-negative integer not presented in the array; for the array [0,1,4,3] MEX equals to 2 because 2 is the minimum non-negative integer not presented in the array. You are given an empty array a=[] (in other words, a zero-length array). You are also given a positive integer x.
You are also given q queries. The j-th query consists of one integer yj and means that you have to append one element yj to the array. The array length increases by 1 after a query.
In one move, you can choose any index i and set ai:=ai x or ai:=ai−x (i.e. increase or decrease any element of the array by x). The only restriction is that ai cannot become negative. Since initially the array is empty, you can perform moves only after the first query.
You have to maximize the MEX (minimum excluded) of the array if you can perform any number of such operations (you can even perform the operation multiple times with one element).
You have to find the answer after each of q queries (i.e. the j-th answer corresponds to the array of length j).
Operations are discarded before each query. I.e. the array a after the j-th query equals to [y1,y2,…,yj].
给定Q个询问和一个值x,每次询问向空数组中插入一个数,对于一个数可以进行无限次的加x和减x的操作,对于每次询问,求最大的mex值
思路
首先是我的暴力做法:
由于每次都可以进行加减 x x x的操作,所以可以保存插入的数对 x x x求余的结果,如果一个数字对 x x x求余后的余数已经存在,则该数字为a[i]=(value%x) (cnt[value%x]-1)*x;
。当处理完插入的q个数字以后,就从头开始处理,如果ans没有出现过,则输出ans,否则就找到最小的没有出现过的ans。第一次暴力时,对于没有出现过的ans,我选择从头开始找,结果在第三个样例TLE。后来考虑维护一个最大值,因为答案保证一定在 [ a n s , m a x n 1 ] [ans,maxn 1] [ans,maxn 1]这个区间内,所以每次就在这个区间范围内找答案即可。
然后是题解做法:
由于每次可以任意次数的加减 x x x,所以我们可以使用一个数组来记录余数的个数,最后用ans去递增查询是否满足要求,如果num[ans%x]的值不为0,则说明之前有一个没有发挥作用的数可以顶替ans,则让ans 1去查询下一个。
(和我的思路差不多,只是优化的更多)
AC代码
1.暴力做法
代码语言:javascript复制#include<bits/stdc .h>
#define x first
#define y second
#define PB push_back
#define mst(x,a) memset(x,a,sizeof(x))
#define all(a) begin(a),end(a)
#define rep(x,l,u) for(ll x=l;x<u;x )
#define rrep(x,l,u) for(ll x=l;x>=u;x--)
#define sz(x) x.size()
#define ins(x) inserter(x,x.begin())
#define IOS ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<long,long> PLL;
typedef pair<char,char> PCC;
typedef long long ll;
const int N=4*1e5 10;
const int M=1e6 10;
const int INF=0x3f3f3f3f;
const int MOD=1e9 7;
ll a[N];
void solve(){
int q,value;cin>>q>>value;
map<int,int> cnt;
map<ll,int> used;
rep(i,0,q){
int x;cin>>x;
x%=value;
cnt[x] ;
a[i]=x (cnt[x]-1)*value;
}
ll ans=0,maxn=0;
rep(i,0,q){
used[a[i]]=1;
maxn=max(maxn,a[i]);
if(!used[ans]) cout<<ans<<endl;
else{
//优化
rep(j,ans,maxn 2){
if(!used[j]){
ans=j;
break;
}
}
cout<<ans<<endl;
}
}
}
int main(){
IOS;
//int t;cin>>t;
//while(t--){
solve();
//}
return 0;
}
2.题解做法
代码语言:javascript复制#include<bits/stdc .h>
#define x first
#define y second
#define PB push_back
#define mst(x,a) memset(x,a,sizeof(x))
#define all(a) begin(a),end(a)
#define rep(x,l,u) for(ll x=l;x<u;x )
#define rrep(x,l,u) for(ll x=l;x>=u;x--)
#define sz(x) x.size()
#define ins(x) inserter(x,x.begin())
#define IOS ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<long,long> PLL;
typedef pair<char,char> PCC;
typedef long long ll;
const int N=4*1e5 10;
const int M=1e6 10;
const int INF=0x3f3f3f3f;
const int MOD=1e9 7;
int cnt[N];
void solve(){
int q,x;cin>>q>>x;
int ans=0;
while(q--){
int y;cin>>y;
cnt[y%x] ;
while(cnt[ans%x]){
cnt[ans%x]--;
ans ;
}
cout<<ans<<endl;
}
}
int main(){
IOS;
//int t;cin>>t;
//while(t--){
solve();
//}
return 0;
}