cf1288 E. Messenger Simulator

题意:

有个联系人列表,当 \(i\) 给你发消息,\(i\) 就会被置顶。现在 \(a[]\) 依次给你发来消息,问每个联系人的历史最高位置和最低位置

思路:

树状数组记录每个位置有没有人

\(x\) 发来消息,把 \(x\) 提到最前面。但是怎么提呢?在树状数组的前面留一堆空位就好了!

不用每次都更新所有人的答案,只需要在 \(x\) 发来消息的时候更新 \(x\) 的答案。最后把所有人的再更新一遍。

int n, m, p[N], mn[N], mx[N];//当前位置,最小位置,最大位置

signed main() {
    iofast;
    cin >> n >> m;

    for(int i = 1; i <= n; i++) //初始
        mn[i] = mx[i] = i,
        p[i] = i + m, add(p[i], 1);//前面留m个空位

    for(int i = m; i; i--) { //i就是要放的空位
        int x; cin >> x;
        mn[x] = 1; //更新最小位置
        mx[x] = max(mx[x], ask(p[x])); //更新最大位置

        add(p[x], -1), add(p[x] = i, 1);
    }

    for(int i = 1; i <= n; i++)
        mx[i] = max(mx[i], ask(p[i])),
        cout << mn[i] << ' ' << mx[i] << endl;
}

posted @ 2022-04-18 23:12  Bellala  阅读(27)  评论(0)    收藏  举报