原题在此
 
某位大佬用线段树做的
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=3e5+7;
inline int read(){
    int sum=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)){sum=sum*10+c-'0';c=getchar();}
    return sum*f;
}
int n,m,s[2*N],lt[N];
int minx[N],maxn[N];
struct Tree{
   int l,r;
   int sum;
   Tree(){sum=0;}
}t[7*N];
inline void build(int p,int l,int r){
   t[p].l=l,t[p].r=r;
   if(l==r) return;
   int mid=(l+r)>>1;
   build(p*2,l,mid);
   build(p*2+1,mid+1,r);
}
inline int q_sum(int p,int ql,int qr){
   int l=t[p].l,r=t[p].r;
   if(l==r) return t[p].sum;
   if(ql<=l&&qr>=r) return t[p].sum;
   int mid=(l+r)>>1;
   if(ql<=mid&&qr>mid) return q_sum(p*2,ql,mid)+q_sum(p*2+1,mid+1,qr);
   if(qr<=mid) return q_sum(p*2,ql,qr);
   if(ql>mid) return q_sum(p*2+1,ql,qr);
   return 0;
}
inline void revise(int p,int x,int w){//将x位改为w 
   int l=t[p].l,r=t[p].r;
   if(l==r){
        t[p].sum=w;
        return;
   }
   int mid=(l+r)>>1;
   if(l<=x&&x<=mid) revise(p*2,x,w);
   else revise(p*2+1,x,w);
   t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
int main(){
    n=read(),m=read();
    build(1,1,n+m);
    for(int i=n;i>=1;i--){
      s[n-i+1]=i,lt[i]=n-i+1;
      revise(1,n-i+1,1);
      minx[i]=i;    
    }
    for(int i=n+1;i<=n+m;i++){
      s[i]=read();
      minx[s[i]]=1;
      maxn[s[i]]=max(maxn[s[i]],q_sum(1,lt[s[i]],i));
      revise(1,lt[s[i]],0);
      revise(1,i,1);
      lt[s[i]]=i;
    }
    for(int i=1;i<=n;i++)
      maxn[i]=max(maxn[i],q_sum(1,lt[i],n+m));
    for(int i=1;i<=n;i++)
      printf("%d %d\n",minx[i],maxn[i]);
}
 
俺用莫队做的
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<set>
using namespace std;
int N,CC[300005],rank[300005],tree[3000005],front[300005],Q,Size,ans,cs[300005],vis4[300005],p1[300005],n,m,vis1[300005],vis[300005][2],a[300005],p[300005];
int Max(int XXX,int YYY){
    if(XXX<YYY) return YYY;
    return XXX;
}struct Node{
    int id,val;
}cx1[300005];
int Cmp(Node q,Node w){
    if(q.val==w.val) return q.id<w.id;
    return q.val<w.val;
}
struct node{
    int l,r,num;
}cx[300005];
int cmp(node XXX,node YYY){
    if(XXX.l/Size==YYY.l/Size) return XXX.r<YYY.r;
    return XXX.l/Size<YYY.l/Size;
}
int del(int X){
    cs[a[X]]--;
    if(cs[a[X]]==0) ans--;
    return 0;
}
int add(int X){
    if(cs[a[X]]==0) ans++;
    cs[a[X]]++;
    return 0;
}
void insert(int po,int d){
    for(;po<=N;po+=po&-po) tree[po]+=d; 
}
int query(int po){
    int sum=0;
    for(;po;po-=po&-po) sum+=tree[po];
    return sum;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d",&a[i]);
        vis1[a[i]]++;
        vis[a[i]][0]=1;
        p[a[i]]=1;
    }
    for(int i=1;i<=n;i++) p[i]+=p[i-1];
    for(int i=1;i<=m;i++){
        if(vis1[a[i]]==1){
            if(i!=m){
                cx[++Q].l=i+1;
                cx[Q].r=m;
                cx[Q].num=a[i];
            }
            cx1[++N].val=a[i];
            cx1[N].id=N;
            CC[N]=a[i];
        }
        else{
            if(vis4[a[i]]==0){
                cx1[++N].val=a[i];
                cx1[N].id=N;
                CC[N]=a[i];
                front[a[i]]=i+1;
                vis4[a[i]]++;
            }
            else{
                vis4[a[i]]++;
                if(vis4[a[i]]==vis1[a[i]]){
                    if(front[a[i]]!=i){
                        cx[++Q].l=front[a[i]];
                        cx[Q].r=i-1;
                        cx[Q].num=a[i];
                    }
                    front[a[i]]=i+1;
                    if(front[a[i]]!=m+1){
                        cx[++Q].l=front[a[i]];
                        cx[Q].r=m;
                        cx[Q].num=a[i];
                    }
                    
                }
                else{
                    if(front[a[i]]!=i){
                        cx[++Q].l=front[a[i]];
                        cx[Q].r=i-1;
                        cx[Q].num=a[i];
                        front[a[i]]=i+1;
                    }
                }
            }
        }
    }
    sort(cx1+1,cx1+1+N,Cmp);
    for(int i=1;i<=N;i++) rank[cx1[i].id]=i;
    for(int i=1;i<=N;i++){
        insert(rank[i],1);
        vis[CC[i]][1]=CC[i]+i-query(rank[i]);
    }
    
    Size=(int)sqrt(m);
    sort(cx+1,cx+Q+1,cmp);
    int l=1,r=0;
    for(int i=1;i<=Q;i++){
        int L=cx[i].l,R=cx[i].r;
        while(l<L) del(l++);
        while(l>L) add(--l);
        while(r<R) add(++r);
        while(r>R) del(r--);
        vis[cx[i].num][1]=Max(vis[cx[i].num][1],ans+1);
    }
    for(int i=1;i<=n;i++){
        if(vis[i][0]!=1){
            vis[i][0]=i;
            vis[i][1]=i+(p[n]-p[i]);
        }
    }
    for(int i=1;i<=n;i++){
        printf("%d %d\n",vis[i][0],vis[i][1]);
    }
}