题目链接:http://codeforces.com/contest/1288/problem/E
参考:https://www.cnblogs.com/pixel-Teee/p/12203233.html
题意:给定一个初始序列1,2,3…,n.m次操作,每次将
提到第一位,求整个过程中,每个数出现的最左和左右的位置,并输出。
题解:模拟,每次提数,将选中的数向前提,被提到的数,则其最左边是1,最右可以用树状数组前缀和计算。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=300010;
int n,m;
int sum[maxn<<1];
int l[maxn],r[maxn];
int a[maxn],pos[maxn];
int lowbit(int x){
return x&(-x);
}
void update(int x,int val){
for(int i=x;i<(maxn<<1);i+=lowbit(i)){
sum[i]+=val;
}
}
int query(int x){
int res=0;
for(int i=x;i;i-=lowbit(i))
res+=sum[i];
return res;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
l[i]=r[i]=i;
pos[i]=i+m;
update(i+m,1);
}
for(int i=1,x;i<=m;i++){
scanf("%d",&x);
l[x]=1;
r[x]=max(r[x],query(pos[x]));
update(pos[x],-1);
pos[x]=m-i+1;
update(pos[x],1);
}
for(int i=1;i<=n;i++){
r[i]=max(r[i],query(pos[i]));
printf("%d %d\n",l[i],r[i]);
}
return 0;
}