トピックリンク:
1288Eメッセンジャーシミュレータcodeforces
アイデアを:
1.各数値について、その最小値が左端に移動させることのいずれか1であるか、または最初の位置であり、
最大値を計算するための2としては、貪欲な思想は:数があることがある場合移動、私たちはどのように多くの左のモバイルコンピューティングの数を見て前に、すべてのモバイル・コンピューティングの終了後に同じ時にも見なければならない。最大値は、すべての歴史的な最大計算値をとり、
どのように多くのそれの数の計算方法をすばやく3を残しましたか?この動的プレフィックスそしてもちろん、それの左側にある状況をシミュレートする方法フェンウィックツリー、と?我々は最初に、各移動がMポジションを埋めるために右から左である、Mビット配列値が0の左端の点に配置することができる。
コード:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 5;
int n, m, N, a[maxn], bit[maxn << 1];
int mn[maxn], mx[maxn], pos[maxn];
#define lowbit(i) (i&-i)
inline void add(int i, int x){
while(i <= N) bit[i] += x, i += lowbit(i);
}
inline int sum(int i){
int ans = 0;
while(i) ans += bit[i], i -= lowbit(i);
return ans;
}
int main() {
#ifdef MyTest
freopen("Sakura.txt", "r", stdin);
#endif
scanf("%d %d", &n, &m);
N = n + m;
for(int i = 1; i <= m; i++) scanf("%d", a + i);
for(int i = 1; i <= n; i++){
mn[i] = mx[i] = i;
add(i + m, 1);
pos[i] = i + m;
}
for(int i = 1; i <= m; i++){
int now = a[i];
mn[now] = 1;
mx[now] = max(mx[now], sum(pos[now]));
add(pos[now], -1);
pos[now] = m - i + 1;
add(pos[now], 1);
}
for(int i = 1; i <= n; i++) mx[i] = max(mx[i], sum(pos[i]));
for(int i = 1; i <= n; i++) printf("%d %d\n", mn[i], mx[i]);
return 0;
}