Messenger Simulator

Polycarp is a frequent user of the very popular messenger. He’s chatting with his friends all the time. He has nn friends, numbered from 11 to nn.

Recall that a permutation of size nn is an array of size nn such that each integer from 11 to nn occurs exactly once in this array.

So his recent chat list can be represented with a permutation pp of size nn. p1p_1 is the most recent friend Polycarp talked to, p2p_2 is the second most recent and so on.

Initially, Polycarp’s recent chat list pp looks like 1,2,,n1,2,…,n (in other words, it is an identity permutation).

After that he receives m messages, the j-th message comes from the friend aja_j. 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]p=[4,1,5,3,2]:

if he gets messaged by friend 3, then p becomes [3,4,1,5,2][3,4,1,5,2];
if he gets messaged by friend 4, then p doesn’t change [4,1,5,3,2][4,1,5,3,2];
if he gets messaged by friend 2, then p becomes [2,4,1,5,3][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 nn and m(1n,m3105)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(1ain)a_1,a_2,…,a_m(1≤a_i≤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][1,2,3,4,5]
  • [3,1,2,4,5][3,1,2,4,5]
  • [5,3,1,2,4][5,3,1,2,4]
  • [1,5,3,2,4][1,5,3,2,4]
  • [4,1,5,3,2][4,1,5,3,2]
    So, for example, the positions of the friend 22 are 2,3,4,4,5,2,3,4,4,5, respectively. Out of these 22 is the minimum one and 55 is the maximum one. Thus, the answer for the friend 22 is a pair (2,5)(2,5).

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

  • [1,2,3,4][1,2,3,4]
  • [1,2,3,4][1,2,3,4]
  • [2,1,3,4][2,1,3,4]
  • [4,2,1,3][4,2,1,3]
    E題好水,完全可以跟D題或者C題交換一下位置
    要找每個編號在序列中出現的最小位置和最大位置。
    可以建一個長度爲n+mn+m的數組ccloc[x]loc[x]表示元素xx在數組中的位置,i=1loc[x]c[i]\sum\limits_{i=1}^{loc[x]}c[i]表示元素xx的當前排名。
    初始狀態c[m+1]c[m+n]c[m+1]\sim c[m+n]賦值爲1,loc[i]={imi[m+1,m+n]0i[1,m]loc[i]=\left\{ \begin{aligned} &i-m \quad\forall i \in\mathbb [m+1,m+n]\\ &0 \quad\forall i \in\mathbb [1,m] \end{aligned} \right.
    每次將一個元素xix_i放在首位,就將c[loc[xi]]c[loc[x_i]]減一,c[mi+1]c[m-i+1]加一,同時更新loc[x]=mi+1loc[x]=m-i+1並更新答案。求排名過程可用樹狀數組維護,時間複雜度爲O(mlog(n+m))O(mlog(n+m))
#include<bits/stdc++.h>

#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector<int>
#define pii pair<int,int>
#define mii unordered_map<int,int>
#define msi unordered_map<string,int>
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<<x<<endl
using namespace std;

inline int qr() {
    int f = 0, fu = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')fu = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        f = (f << 3) + (f << 1) + c - 48;
        c = getchar();
    }
    return f * fu;
}

const int N = 3e5 + 10;
int c[N << 1], n, m, loc[N], ans[N][2], h;

int get_sum(int k) {
    int ans = 0;
    while (k > 0) {
        ans += c[k];
        k -= lowbit(k);
    }
    return ans;
}

void add(int t, int v) {
    while (t <= n + m) {
        c[t] += v;
        t += lowbit(t);
    }
}

int main() {
    n = qr(), m = qr();
    h = m + 1;
    repi(i, 1, n)add(m + i, 1), loc[i] = m + i, ans[i][0] = i;
    repi(i, 1, m) {
        int x = qr();
        ans[x][0] = 1, ans[x][1] = max(ans[x][1], get_sum(loc[x]));
        add(loc[x], -1), add(--h, 1), loc[x] = h;
    }
    repi(i, 1, n)printf("%d %d\n", ans[i][0], max(ans[i][1], get_sum(loc[i])));
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章