• 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
    ",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]
  • 相关阅读:
    类,对象和方法
    jmeter对接口测试入参进行MD5加密
    Jmeter配置代理进行录制
    MYSQL——having 和 where的区别
    MySQL
    Python——面试编程题
    mysql——面试题
    Vue——解决跨域请求问题
    Vue——axios网络的基本请求
    ES6 数组map(映射)、reduce(汇总)、filter(过滤器)、forEach(循环迭代)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12219464.html
Copyright © 2020-2023  润新知