Codeforces 1288E- Messenger Simulator (树状数组)
思路
在前面预留m个空位,每次把一个数提前就放在前面预留的空位。一个数所在的位置就是它后面有多少个数,每次移动的时候更新最大最小值即可。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 2e6 + 10;
int tarr[N];
int pos[N];
int nn;
int lowbit(int x) {
return -x & x;
}
void add(int p, int v) {
while(p <= nn) {
tarr[p] += v;
p += lowbit(p);
}
}
int sum(int p) {
int res = 0;
while(p) {
res += tarr[p];
p -= lowbit(p);
}
return res;
}
int sum(int l, int r) {
return sum(r) - sum(l - 1);
}
int op[N];
int arr[N];
int minans[N];
int maxans[N];
int main() {
ios::sync_with_stdio(false);
int n, m;
cin >> n >> m;
nn = n + m + 1;
for(int i = 0; i < m; i++) {
cin >> op[i];
}
for(int i = 1; i <= n; i++) {
add(m + i, 1);
arr[m + i] = i;
pos[i] = m + i;
minans[i] = maxans[i] = i;
}
int front = m;
for(int i = 0; i < m; i++) {
int p = pos[op[i]];
maxans[op[i]] = max(maxans[op[i]], n - sum(p + 1,nn));
minans[op[i]] = 1;
arr[p] = 0;
arr[front] = op[i];
add(p, -1);
add(front, 1);
pos[op[i]] = front;
front--;
}
for(int i = 1; i <= n; i++) {
maxans[i] = max(maxans[i], n - sum(pos[i] + 1,nn));
cout << minans[i] << " " << maxans[i] << endl;
}
}