Add and Mex(时间复杂度,枚举)

题意

给定一个包含N个元素的序列A=(A1,,AN)

下述操作执行M次:对于每个i,(1iN),将Ai加上i。然后求序列的mex。

题目链接:https://atcoder.jp/contests/abc272/tasks/abc272_e

数据范围

1N,M2×105

思路

首先分析一下,答案的区间。显然是[0,N]

所以如果每个元素的值不在这个区间内,那么它是不起作用的。

因此,第1个元素最多起作用n+1次,第2个元素n/2+1次,...,第N个元素2次。

本题的做法就是先找到每个元素起作用的区间[l,r],然后计算对应的值。设置M个vector,存储在每一次中出现的值。最后遍历一下即可。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long ll;

const int N = 200010;

int n, m;
int a[N];
vector<int> f[N];

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    for(int i = 1; i <= n; i ++) {
        if(a[i] >= n) continue;
        int l = (a[i] >= 0 ? 1 : (-a[i] - 1) / i + 1);
        int r = min(m + 1, (n - a[i] - 1) / i + 1);
        for(int j = l; j < r; j ++) {
            f[j].push_back(a[i] + i * j);
        }
    }
    for(int i = 1; i <= m; i ++) {
        int nx = 0;
        sort(f[i].begin(), f[i].end());
        f[i].erase(unique(f[i].begin(), f[i].end()), f[i].end());
        if(!f[i].size()) {
            printf("0\n");
            continue;
        }
        bool flag = false;
        for(auto p : f[i]) {
            if(p != nx) {
                flag = true;
                printf("%d\n", nx);
                break;
            }
            nx ++;
        }
        if(!flag) printf("%d\n", nx);
    }
    return 0;
}
posted @   pbc的成长之路  阅读(94)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示