码迷,mamicode.com
首页 > 其他好文 > 详细

Educational Codeforces Round 80 E. Messenger Simulator

时间:2020-01-20 22:39:18      阅读:80      评论:0      收藏:0      [点我收藏+]

标签:put   fir   present   def   XML   limit   lis   ssis   shift   

http://codeforces.com/contest/1288/problem/E

 

题意:

有一个长度为n的循环队列,初始第i个位置的数字为i

有m次操作,每次操作把数字x放到队首,原队首与数字x原位置之间的数字在队列中后移一位

输出m次操作过程中,数字i在队列中最靠前和最靠后的位置

 

若数字i没有移动过,

它最靠前的位置就是初始位置i,

最靠后的位置就是初始位置加上移动过的大于它的数字个数

若数字i被移动过

它最靠前的位置就是1

最靠后的位置是max(初始位置加上第一次移动前移动的大于它的数字个数,每相邻两次移动之间移动的不同的数字个数) 

前者可用树状数组,后者可用莫队

 

#include<cmath>
#include<cstdio>
#include<algorithm>
 
#define lowbit(x) x&(-x)
 
using namespace std;
 
#define N 300001
 
int n,m,siz,tmp;
int a[N];
bool vis[N];
 
int nxt[N],suf[N]; 
int use[N];
 
int sum[N],bl[N];
int col[N];
 
int ans[N][2];
 
int cnt[N],g[N];
 
struct node
{
    int l,r,id;
    bool operator < (node p)const
    {
        if(bl[l]!=bl[p.l]) return bl[l]<bl[p.l];
        return r<p.r;
    }    
}e[N];
 
inline void update(int pos,bool w)
{
    if(w) tmp+=(++sum[a[pos]]==1);
    else tmp-=(!--sum[a[pos]]);
}
 
void change(int x)
{
    while(x<=n) 
    {
        cnt[x]++;
        x+=lowbit(x);
    }
}
 
int query(int x)
{
    int s=0;
    while(x)
    {
        s+=cnt[x];
        x-=lowbit(x);
    }
    return s;
}
 
int main()
{
    scanf("%d%d",&n,&m);
    siz=sqrt(m);
    for(int i=1;i<=m;i++) bl[i]=(i-1)/siz+1;
    int x;
    for(int i=1;i<=m;i++) 
    {
        scanf("%d",&x);
        a[i]=x;
        if(vis[x]) continue;
        vis[x]=true;
        g[x]=query(n-x+1);
        change(n-x+1);
        use[x]=1;
    }
    for(int i=n;i;--i) use[i]+=use[i+1];
    for(int i=m;i;--i)
    {
        if(!nxt[a[i]]) suf[i]=m+1;
        else suf[i]=nxt[a[i]];
        nxt[a[i]]=i;
    }
    for(int i=1;i<=m;i++)
    {
        e[i].l=i; e[i].r=suf[i]-1; e[i].id=a[i];        
    }
    sort(e+1,e+m+1);
    int L=1,R=0;
    int u;
    for(int i=1;i<=m;i++)
    {
        while(L>e[i].l) update(--L,true);
        while(L<e[i].l) update(L++,false);
        while(R>e[i].r) update(R--,false);
        while(R<e[i].r) update(++R,true);
        u=tmp-1;
        col[e[i].id]=max(u,col[e[i].id]);
    }
    for(int i=1;i<=n;++i)
        if(!vis[i])
        {
            ans[i][0]=i;
            ans[i][1]=i+use[i];
        }
        else
        {
            ans[i][0]=1;
            ans[i][1]=i+g[i];
            ans[i][1]=max(ans[i][1],col[i]+1);
        }
    for(int i=1;i<=n;++i) printf("%d %d\n",ans[i][0],ans[i][1]);
}

 

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 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 . p1p1 is the most recent friend Polycarp talked to, p2p2 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 mm messages, the jj -th message comes from the friend ajaj . And that causes friend ajaj to move to the first position in a permutation, shifting everyone between the first position and the current position of ajaj by 11 . Note that if the friend ajaj 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 33 , then pp becomes [3,4,1,5,2][3,4,1,5,2] ;
  • if he gets messaged by friend 44 , then pp doesn‘t change [4,1,5,3,2][4,1,5,3,2] ;
  • if he gets messaged by friend 22 , then pp 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 mm (1n,m31051≤n,m≤3⋅105 ) — the number of Polycarp‘s friends and the number of received messages, respectively.

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

Output

Print nn 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
Copy
5 4
3 5 1 4
Output
Copy
1 3
2 5
1 4
1 5
1 5
Input
Copy
4 3
1 2 4
Output
Copy
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,52,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]

Educational Codeforces Round 80 E. Messenger Simulator

标签:put   fir   present   def   XML   limit   lis   ssis   shift   

原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12219464.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!