题解 P3960 【列队】

· · 题解

\mathrm{NOIP2017} 列队

\huge\color{blue}\boxed{\color{Violet}\mathfrak{There\ is \ my \ blog}}

题目意思

\mathrm{Sol}

\mathrm{Code}

#include <bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;

inline int read()
{
    int sum=0,ff=1; char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-') ff=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        sum=sum*10+(ch^48),ch=getchar();
    return sum*ff;
}

const int N=1e7+5;

int n,m,Q,inf,tot,T[N];
vector<int> G[N];

struct Seg
{
    int siz[N],ls[N],rs[N];
    inline int ask(int l,int r,int rt,int x)
    {
        if(l==r) return l;
        int mid=(l+r)/2;
        int now=mid-l+1-siz[ls[rt]];
        if(x<=now) return ask(l,mid,ls[rt],x);
        else return ask(mid+1,r,rs[rt],x-now);
    }
    inline void del(int l,int r,int &rt,int x)
    {
        if(!rt) rt=++tot;
        siz[rt]++;
        if(l==r) return;
        int mid=(l+r)/2;
        if(x<=mid) del(l,mid,ls[rt],x);
        else del(mid+1,r,rs[rt],x);
    }   
    inline int del_lie(int x)
    {
        int pos=ask(1,inf,T[n+1],x);
        del(1,inf,T[n+1],pos);
        return (pos<=n)?(pos-1)*m+m:G[n+1][pos-n-1];
    }
    inline int del_hang(int x,int y)
    {
        int pos=ask(1,inf,T[x],y);
        del(1,inf,T[x],pos);
        return (pos<m)?(x-1)*m+pos:G[x][pos-m];
    }
};
Seg S;

signed main()
{
    n=read();
    m=read();
    Q=read();
    inf=max(n,m)+Q;
    for (;Q--;)
    {
        int x,y;
        x=read();
        y=read();
        if(y==m)
        {
            int P=S.del_lie(x);
            printf("%lld\n",P);
            G[n+1].pb(P);
        }
        else 
        {
            int P=S.del_hang(x,y);
            printf("%lld\n",P);
            G[n+1].pb(P);
            P=S.del_lie(x);
            G[x].pb(P);
        }
    }
    return 0;
}