题目大意:
即a是一个空的数列。a总共插入q次,每一次加入新元素,
假如对于每次得到的新序列,我们都可以对其中的任一个元素做 x的操作,即:
vector<int> a;
for(int i=0;i<q;i++){
a.push_back(yi);
vector<int> tmp =a ;
//ask sth about tmp
for(int j=0;j<(int)tmp.size();j++){
tmp[j]+=ki * x; //ki is not determined
}
}
问我们每加入一个元素时候,通过对每个元素反复的加减x,这个序列中的最小的非负整数 最大是多少?
比如对于序列[0,1,1] 最小的非负整数是2,假如x=1,那么我们可以对第三个元素加1,最后形成序列[0,1,2],那么最小非负整数为3.
数据范围: ,
解题思路:
首先,看到最小最大值问题,我们可以考虑2分,但是2分这里好像不好写,所以换一种思路,这里采取构造的方法来做。首先我们观察到,每次加入一个新的数字,其实我们可以对,这是等价的,通过以下公式推出:
其中k为任意整数。
这时候,我们记录下每个数字在序列中应该加几倍的x,比如第一次得到的我们可以放在原来的位置,下一次假如还有到来,我们把它放在 ,总结来讲:对于第m次出现的,我们把它放在 即可。通过这种构造我们可以尽可能地把数字在区间填满。然后在q次询问中,每次记录下最小的数字即可。最小的数字不可能超过q的范围即4e5。所以找最小的数字复杂度不会超。注意这里范围到1e9,所以需要hash存储,对应c++的map.
#include <bits/stdc++.h>
#define int long long
using namespace std;
int32_t main(){
int q,x;cin>>q>>x;
map<int,int> mm;
set<int> ms;
int mno=0;
for(int i=0;i<q;i++){
int t;cin>>t;
t%=x;
if(mm.count(t))mm[t]++;
else mm[t]=0;
ms.insert(t+mm[t]*x);
if(t+mm[t]*x==mno){
for(int no=mno;;no++){
if(!ms.count(no)){
mno=no;
break;
}
}
}
cout<<mno<<endl;
}
return 0;
}
扫描二维码关注公众号,回复:
10400336 查看本文章