Educational Codeforces Round 80 E. Messenger Simulator

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 (1≤n,m≤3⋅1051≤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 (1≤ai≤n1≤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]

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

时间: 2024-10-09 04:33:41

Educational Codeforces Round 80 E. Messenger Simulator的相关文章

Educational Codeforces Round 80 (Rated for Div. 2)

\[Educational\ Codeforces\ Round\ 80\ (Rated\ for\ Div.\ 2)\] A.Deadline 打勾函数找最小值,在\(\sqrt{d}\)邻域里找\(x\)最小化\(x+\lceil\frac{d}{x+1}\rceil\)即可 //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace

Educational Codeforces Round 80 A-E简要题解

contest链接:https://codeforces.com/contest/1288 A. Deadline 题意:略 思路:根据题意 x + [d/(x+1)] 需要找到一个x使得上式小于等于n,即x + [d/(x+1) ] <=n,不等式两边同时+1得 x+1 + [d/(x+1)] <=n + 1当且仅当(x+1)2 = d时,式子左边最小,所有只需要判断一下最小值是否<=n+1就可以知道该不等式是否存在x满足题意了,即找到x = √d - 1,判断一下即可. AC代码:

Educational Codeforces Round 80 D E

A了三题,rk1000左右应该可以上分啦,开??. 后面的D,E比赛时就感觉可做,但又想不到方法. 然后我补了下,确实如此. D - Minimax Problem 题意:很简单,给一个矩阵,找两行序列i,j,使得通过每个元素取当列最大合成出来的序列,最小值最大. hit 1:比赛里我是真的有想二分,最小值最大,这不是经典二分答案套路嘛. hit 2:比赛里我也是真的有注意到这个m <=8 给的很小,想以此为突破点干点啥? 然后要么太晚了,要么我做了三题自满了,总之没想到最终解法就睡觉了. 其实

Educational Codeforces Round 80 (Rated for Div. 2) 题解

Deadline Yet Another Meme Problem Two Arrays Minimax Problem Messenger Simulator Deadline \[ Time Limit: 2 s\quad Memory Limit: 256 MB \] 这是个对勾函数,所以最小的话是在 \(sqrt\) 位置,所以只要找这附近的数字就可以了. view /************************************************************

Educational Codeforces Round 80

QAQ: 其中C,D,E题的思路来自 https://www.bilibili.com/video/av83609526?p=5 A. Deadline 题意: 给出一个式子对于给出的d,求当x是整数时的最小解. 思路: 简单数学题,这个式子变形一下就是我们中学学的对号函数,但要注意下向上取整和整数x 代码: #include <bits/stdc++.h> using namespace std; typedef long long LL; int main() { int T; LL n,

Educational Codeforces Round 80 (Rated for Div. 2)(C - Two Arrays )

C - Two Arrays 题目链接:https://codeforces.com/contest/1288/problem/C 题目: 题意:给你n,m,利用1~n之间的数(可重复)来组成长度为m的数组a,b,要求数组a非递减,数组b非递增,且a数组的数<=b数组中的数,求出a,b数组对数 思路:用动态规划,dp[i][j]是第i个位置放数字j的方案数,根据题意可以将b数组反置然后接在a后面,则该数组长度为2m,为一个非递减序列,则就是求1~n这些数字可重复组成多少种长度为2m的非递减序列,

Educational Codeforces Round 80 (Rated for Div. 2)参加感悟

这次比赛有14000+的人报名,结果我得了266名,创了新纪录. 进过这次比赛,我有回答了1800+. 寒假到了,又可以每次比赛都打了.平时进步很慢,我希望能在寒假有更大的进步. 作为寒假第一场比赛,发挥让我还是很满意的. 开始讲题: A: http://codeforces.com/contest/1288/problem/A 这题太水了,直接是sqrt(d)-1和sqrt(d),如果它们不行,那么其他的也肯定不行. 直接上代码: 1 #include<bits/stdc++.h> 2 #d

Educational Codeforces Round 80 C. Two Arrays

http://codeforces.com/contest/1288/problem/C 题意: 用1—n构造两个长为m的数组a,b 满足a[i]<=b[i],a单调不减,b单调不增 求方案数 令dp[i][j][k] 表示构造了长度为i,a[i]=j,b[i]=k的方案数 dp[i][j][k]=Σ dp[i-1][h][p] (h<=p,h<=i,p>=k) 时间复杂度:m*n^4 前缀和.后缀和 优化: sum[i][j][k] 表示 Σ dp[i][1—j][k—n] 求的

Educational Codeforces Round 80. A - Deadline

题面:https://codeforces.com/contest/1288/problem/A 题目大意: Adilbek有一个特殊项目,他需要运行这个项目得到结果. 但是这个项目直接运行需要消耗d天时间. 他也可以选择优化程序以减少程序运行消耗时间. 假设他用了x天优化程序,那么最后运行程序只需要消耗天的时间(括号指向上取整). 那么总共需要消耗的天数是. 问,他能不能在n天内得到结果? 解题思路: 问能不能在n天内得到结果,只需要求出最少需要的天数与n对比即可. 可得到 那么总天数为 当且