cf Educational Codeforces Round 80 E. Messenger Simulator

E. Messenger Simulator
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Polycarp is a frequent user of the very popular messenger. He’s chatting with his friends all the time. He has n friends, numbered from 1 to n.
Recall that a permutation of size n is an array of size n such that each integer from 1 to n occurs exactly once in this array.

So his recent chat list can be represented with a permutation p of size n. p1 is the most recent friend Polycarp talked to, p2 is the second most recent and so on.

Initially, Polycarp’s recent chat list p looks like 1,2,…,n

(in other words, it is an identity permutation).

After that he receives m messages, the j-th message comes from the friend aj. And that causes friend aj to move to the first position in a permutation, shifting everyone between the first position and the current position of aj by 1. Note that if the friend aj is in the first position already then nothing happens.

For example, let the recent chat list be p=[4,1,5,3,2]:
if he gets messaged by friend 3, then p becomes [3,4,1,5,2];
if he gets messaged by friend 4, then p doesn’t change [4,1,5,3,2];
if he gets messaged by friend 2, then p becomes [2,4,1,5,3].

For each friend consider all position he has been at in the beginning and after receiving each message. Polycarp wants to know what were the minimum and the maximum positions.
Input

The first line contains two integers n and m (1≤n,m≤3⋅10^5) — the number of Polycarp’s friends and the number of received messages, respectively.

The second line contains m integers a1,a2,…,am (1≤ai≤n) — the descriptions of the received messages.
Output

Print n

pairs of integers. For each friend output the minimum and the maximum positions he has been in the beginning and after receiving each message.
Examples
Input

5 4
3 5 1 4

Output

1 3
2 5
1 4
1 5
1 5

Input

4 3
1 2 4

Output

1 3
1 2
3 4
1 4

Note

In the first example, Polycarp’s recent chat list looks like this:

[1,2,3,4,5]
[3,1,2,4,5]
[5,3,1,2,4]
[1,5,3,2,4]
[4,1,5,3,2]

So, for example, the positions of the friend 2 are 2,3,4,4,5, respectively. Out of these 2 is the minimum one and 5 is the maximum one. Thus, the answer for the friend 2 is a pair (2,5).

In the second example, Polycarp’s recent chat list looks like this:

[1,2,3,4]
[1,2,3,4]
[2,1,3,4]
[4,2,1,3]

中文:

手機裏有n個好友的消息列表,初始使每個好友的序列按順序排列,每次好友來消息的時候,好友會從消息列表的當前位置跳到第一個位置,現在給出每個每個m個數,表示好友來消息的順序,最後問你每個好友在消息列表中位置最大和最小是多少。

代碼:

#include<bits/stdc++.h>

using namespace std;
const int maxn = 6e5 + 1;
const int N = 3e5 + 1;

int c[maxn];
int a[N];
int mi[N],ma[N];
int n,m;

int lowbit(int x)
{
    return x&(-x);
}

void add(int pos,int val)
{
    while(pos<maxn)
    {
        c[pos]+=val;
        pos+=lowbit(pos);
    }
}
int query(int pos)
{
    int sum = 0;
    while(pos)
    {
        sum+=c[pos];
        pos-=lowbit(pos);
    }
    return sum;
}

int main()
{
    ios::sync_with_stdio(false);
    while(cin>>n>>m)
    {
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++)
        {
            a[i]=i + m;
            ma[i]=mi[i]=i;
            add(i+m,1);
        }
        int x;
        int f = m;
        for(int i=1;i<=m;i++)
        {
            cin>>x;
            mi[x]=1;
            int res = query(a[x]);
            ma[x]=max(ma[x],res);
            add(a[x],-1);
            a[x]=f;
            add(a[x],1);
            f--;
        }
        for(int i=1;i<=n;i++)
        {
            ma[i]=max(ma[i],query(a[i]));
        }
        for(int i=1;i<=n;i++)
        {
            cout<<mi[i]<<" "<<ma[i]<<endl;
        }
    }
	return 0;
}

解答:

E題過了400多人,想必比較簡單,果不其然-_-

題目給你n個人,m個數表示好友來消息的順序。由於數據規模的限制,肯定要用一種數據結構維持數據的變化。
首先最小位置,如果消息列表中某個好友的位置沒有發生過改變,那麼最小位置就是當前位置,如果發生過改變,即來到第一個位置,那麼最小位置就是1。
關鍵在於計算最大位置,這裏利用樹狀數組或使用線段樹維持一個前綴和,用來記錄在列表中,每個好友前面有多少個人,就表示所在的位置了。假如當前將第i個好友移動到第一個位置,那麼在前綴和中,需要先將大於等於i位置的前綴和全部減1,然後由於有m個好友發來消息會插入到消息列表的頭部,所以在將所有大於1的位置的前綴和全部加1。
對應到樹狀數組的數據結構上,描述爲對某個單點進行+1或-1的操作,每次查詢時得到前綴和表示修改位置後的列表每個人所對應在列表中的新位置。
由於只有m個好友發消息,那麼先在前面預留出m個空位置即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章