Loading

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;
}
posted @ 2022-10-09 11:01  dgsvygd  阅读(86)  评论(0编辑  收藏  举报