[Tree line] Codeforces 1288E Messenger Simulator

Subject to the effect

A length \ (n-\) buddy list from top to bottom is \ (. 1 \ n-SIM \) , you are sequentially received \ (m \) messages, the \ (I \) message is \ ( a_i \) sent, then \ (a_i \) will jump to the top of a list of conversations, the other the original sequence extended, seeking \ (1 \ sim n \) each buddy on the outermost and innermost positions location under.
\ (. 1 \ n-Leq, m \ Leq. 3 \ ^ 10. 5 Times \) .

answer

First consider how to deal with the rearmost position. Because if a friend moved to the top, then in addition to his everyone will move down, it is clear that in addition to his position on the innermost everyone does not contribute directly to the mobile of the person the closest to the location can be set to 1.

Consider how to deal with the lowermost position. Easy to find a person to move on to face the most lowermost position of others only to rise. So we just need to put every \ (x \) to move to the top when asked about \ (x \) position before the move, and then completed all mobile asking everyone at the current location, and then ask for before each move after the result of the inquiry results are completed and all movement can take max. We can \ (\ n-) front positions plus a row of \ (m \) imaginary point indicates that a 0 \ (n-+ m \) th positions not occupied position, the position 1 represents occupied and then maintain with tree line. Record the current position of each point. The move to the front just a point to move those virtual point, ask the current position of the point with a single query to 1 before the number of prefixes and that the points.

Time complexity \ (O ((N + M) log (N + M)) \) .

This operation built a virtual point of feeling a little clever, under study.

Code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

#define RG register int
#define LL long long

template<typename elemType>
inline void Read(elemType &T){
    elemType X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    T=(w?-X:X);
}

int SegTree[2400100];
int AnsA[300010],AnsB[300010],Pos[300010];
int N,M;

void Build_SegTree(int Root,int L,int R){
    if(L==R){
        if(L>M) SegTree[Root]=1;
        return;
    }
    int mid=(L+R)>>1;
    Build_SegTree(Root<<1,L,mid);
    Build_SegTree(Root<<1|1,mid+1,R);
    SegTree[Root]=SegTree[Root<<1]+SegTree[Root<<1|1];
    return;
}

int Query(int Root,int L,int R,int QL,int QR){
    if(R<QL||QR<L) return 0;
    if(QL<=L && R<=QR) return SegTree[Root];
    int mid=(L+R)>>1;
    return Query(Root<<1,L,mid,QL,QR)+Query(Root<<1|1,mid+1,R,QL,QR);
}

void Update(int Root,int L,int R,int pos,int Add){
    if(L==R){SegTree[Root]+=Add;return;}
    int mid=(L+R)>>1;
    if(pos<=mid) Update(Root<<1,L,mid,pos,Add);
    else Update(Root<<1|1,mid+1,R,pos,Add);
    SegTree[Root]=SegTree[Root<<1]+SegTree[Root<<1|1];
    return;
}

int main(){
    Read(N);Read(M);
    Build_SegTree(1,1,N+M);
    for(RG i=1;i<=N;++i){
        AnsA[i]=AnsB[i]=i;
        Pos[i]=M+i;
    }
    for(RG i=1;i<=M;++i){
        int x;Read(x);AnsA[x]=1;
        AnsB[x]=max(AnsB[x],Query(1,1,N+M,1,Pos[x]));
        Update(1,1,N+M,Pos[x],-1);
        Update(1,1,N+M,M-i+1,1);
        Pos[x]=M-i+1;
    }
    for(RG i=1;i<=N;++i){
        AnsB[i]=max(AnsB[i],Query(1,1,N+M,1,Pos[i]));
        printf("%d %d\n",AnsA[i],AnsB[i]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/AEMShana/p/12635489.html