题目意思:对于给定的i,i从1到m,需要找到含有1~i全部数字的最小区间长度,其实就是求mex。

我们可以维护这样一个W[l][i],表示以l作为左端点满足要求的最短区间的r的位置,那么当我们计算i+1是,设i+1出现位置的序列为p,那么我们对任意一个l处在两个区间(p[k],p[k+1])内w[l[[i],可以得到w[l][i+1]=max{w[l][i],p[i+1][k+1]},从而完成转移,注意对于最后一段,要全部赋值为无穷,这样子就可以把问题变成区间赋值问题

#include<bits/stdc++.h>
using namespace  std;
const int N=2e5+10;
struct node
{
    int l,r,laz,vmi,vr;
}t[N<<2];

int n,x,m;
vector<int> v[N];

void pushdown(int i)
{
    if (!t[i].laz) return;
    t[i<<1].vmi=t[i].laz-t[i<<1].r;
    t[i<<1].vr=t[i<<1].laz=t[i].laz;
    t[i<<1|1].vmi=t[i].laz-t[i<<1|1].r;
    t[i<<1|1].vr=t[i<<1|1].laz=t[i].laz;
    t[i].laz=0;
}

void build(int i,int l,int r)
{
    t[i].l=l,t[i].r=r,t[i].vmi=t[i].laz=0;
    if (l==r) {t[i].vr=l,t[i].vmi=0; return;}
    int mid=(l+r)>>1;
    build(i<<1,l,mid),build(i<<1|1,mid+1,r);
    t[i].vr=t[i<<1|1].vr;
}

void change(int i,int l,int r,int v)
{
    if (t[i].l==l&&t[i].r==r)
    {
        t[i].laz=t[i].vr=v;
        t[i].vmi=v-t[i].r;
        return;
    }
    pushdown(i);
    int mid=(t[i].l+t[i].r)>>1;
    if (r<=mid) change(i<<1,l,r,v); else
    if (l>mid) change(i<<1|1,l,r,v); else
    change(i<<1,l,mid,v),change(i<<1|1,mid+1,r,v);
    t[i].vr=t[i<<1|1].vr;
    t[i].vmi=min(t[i<<1].vmi,t[i<<1|1].vmi);
}

int find(int i,int v)
{
    if (t[i].l==t[i].r) 
    {
        if (t[i].vr<=v) return t[i].l;
        else return t[i].l-1;
    }
    pushdown(i);
    int mid=(t[i].l+t[i].r)>>1;
    if (t[i<<1].vr<=v) return find(i<<1|1,v);
    return find(i<<1,v);
}

int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1; i<=m; i++) v[i].push_back(0);
    for (int i=1; i<=n; i++) scanf("%d",&x),v[x].push_back(i);
    build(1,1,n);
    
    for (int i=1; i<=m; i++)
    {
        int sz=v[i].size();
        if (v[i][sz-1]<n) change(1,v[i][sz-1]+1,n,1000000000);
        for (int j=sz-1; j>=0; j--)
        {
            int nw=find(1,v[i][j]);
            if (nw>v[i][j-1]&&j) change(1,v[i][j-1]+1,nw,v[i][j]);
        }
        printf("%d%c",t[1].vmi+1,i==m?'\n':' ');
    }
    return 0;
}