http://codeforces.com/contest/1288/problem/E
题意:
给出一个序列1到n,现在有m次操作,每次将一个数提到序列首。问每个数的最大位置和最小位置。
解析:
最小位置:被提过为1,否则为起始位置
最大位置:
先看 第 次提到队首和第 次,显然此时可能产生的最大值为:操作序列两个位置中间出现的所有其他数的种数,即区间不同数的个数。
而 在第一次被提到队首之时的最大位置为: 操作序列中之前出现过的大于 的数量。
假设初始序列为 ,操作序列为 ,那么对于3来说,就是3(原来位置)+1(操作3之前操作过4)
这个相当于不算小于 的数的:区间不同数的个数,这个怎么做?我们可以这样:操作序列变为 ,这样默认将小于 的算且只算一次。此时的3的答案为 。
代码:
/*
* Author : Jk_Chen
* Date : 2020-01-13-19.12.30
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
#define debug(x) cerr<<#x<<" = "<<x<<'\n'
const LL mod=1e9+7;
const int maxn=1e6+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
int a[maxn];
int mx[maxn],mi[maxn];
vector<int>V[maxn];
int K;
int idx(int pos){return pos/K; }
struct node{
int l,r,id;
bool operator<(const node &a)const{
return idx(l)<idx(a.l)||idx(l)==idx(a.l)&&r<a.r;
}
}q[maxn];
int times[maxn];
int main(){
int n=rd,m=rd;
K=sqrt(n+m);
rep(i,1,n)mi[i]=i,mx[i]=i;
rep(i,1,n)a[i]=n-i+1,V[a[i]].pb(i);
rep(i,1,m){
a[i+n]=rd;
mi[a[i+n]]=1;
V[a[i+n]].pb(i+n);
}
rep(i,1,n)V[i].pb(n+m+1);
int cnt=0;
rep(i,1,n){
if(V[i].size()>1){
rep(j,1,V[i].size()-1){
if(V[i][j-1]+1<V[i][j]){
q[++cnt].id=i;
q[cnt].l=V[i][j-1]+1;
q[cnt].r=V[i][j]-1;
//debug(q[cnt].id<<" "<<q[cnt].l<<" "<<q[cnt].r);
}
}
}
}
sort(q+1,q+1+cnt);
int L=q[1].l,R=q[1].l-1;
int kinds=0;
rep(i,1,cnt){
while(R<q[i].r)if((times[a[++R]]++)==0)kinds++;
while(L>q[i].l)if((times[a[--L]]++)==0)kinds++;
while(R>q[i].r)if((--times[a[R--]])==0)kinds--;
while(L<q[i].l)if((--times[a[L++]])==0)kinds--;
//debug(q[i].l<<" "<<q[i].r<<" "<<kinds);
mx[q[i].id]=max(mx[q[i].id],kinds+1);
}
rep(i,1,n)
printf("%d %d\n",mi[i],mx[i]);
}