AtCoder Beginner Contest 272 E Add and Mex
Add and Mex
模拟
照着模拟就行了,主要是复杂度分析
第 \(i\) 个数字的增长速度为 \(i\),显然对最终答案造成影响的范围值域就在 \([0, n]\)
在最不理想的情况下,计算量为 \(\sum_{i=1}^{n}\lceil \frac{n + 1}{i} \rceil\)
不难看出就是一个调和级数,计算量为 \((n + 1)\sum_{i=1}^{n}\frac{1}{i}\)
时间复杂度为 \(O(nlogn)\)
这个模拟也是要讲究的,就只模拟那个值在 \([0, n]\) 范围内
#include <iostream>
#include <cstdio>
#include <queue>
#include <array>
using namespace std;
typedef long long ll;
#define pii pair<ll, ll>
const int maxn = 2e5 + 10;
vector<pii>gra[maxn];
int alp[maxn];
int n, m;
int query()
{
int ans = 0;
while(alp[ans]) ans++;
return ans;
}
int main()
{
cin >> n >> m;
queue<pii>q;
for(int i=0; i<n; i++)
{
ll x;
cin >> x;
if(x > n) continue;
else if(x < 0)
{
ll way = (-x + i) / (i + 1), nex = way * (i + 1) + x;
if(way <= m && nex <= n) gra[way].push_back({nex, i + 1});
}
else {q.push({x, i + 1}); alp[x]++;}
}
for(int i=1; i<=m; i++)
{
int len = q.size();
for(int j=0; j<len; j++)
{
auto [now, val] = q.front();
q.pop();
alp[now]--;
if(now + val <= n)
{
q.push({now + val, val});
alp[now + val]++;
}
}
for(auto x : gra[i])
{
q.push(x);
alp[x.first]++;
}
cout << query() << "\n";
}
return 0;
}