Codeforces 1288E- Messenger Simulator (树状数组)

Description

思路

在前面预留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;
    }
    
}
posted @ 2020-05-07 23:05  limil  阅读(118)  评论(0编辑  收藏  举报