题目链接:Codeforces - Messenger Simulator
我们考虑最前面的位置,当且仅当当前这个人往前面走的时候才会往前,否则无论如何位置要么不变,要么往后移动。所以我们考虑最后的位置即可。最后的位置其实就是看前面有多少人,那么我们可以用树状数组维护前面多少人即可,因为都是往前面移动,所以我们最开始的位置从m+1开始即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=3e5+10;
int d[N<<1],n,m,l[N],r[N],pos[N],len;
inline void add(int x,int v){for(x;x<=len;x+=(x&(-x))) d[x]+=v;}
inline int ask(int x){int s=0; for(;x;x-=(x&(-x))) s+=d[x]; return s;}
signed main(){
cin>>n>>m; len=n+m;
iota(l+1,l+1+n,1); iota(r+1,r+1+n,1);
for(int i=1;i<=n;i++) pos[i]=m+i,add(pos[i],1);
for(int i=1,x;i<=m;i++){
scanf("%d",&x); l[x]=1;
r[x]=max(r[x],ask(pos[x]));
add(pos[x],-1); pos[x]=m+1-i; add(pos[x],1);
}
for(int i=1;i<=n;i++) r[i]=max(r[i],ask(pos[i]));
for(int i=1;i<=n;i++) printf("%d %d\n",l[i],r[i]);
return 0;
}