https://www.luogu.org/problemnew/show/P3960

 

p<=500 50分 模拟

每个人的出队只会影响当前行和最后一列

p<=500,有用的行只有500行

所以只维护这p行和最后一列的信息

然后模拟

时间复杂度:O(p*(n+m))

空间复杂度:O(p*m+n)

 

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

#define N 501
#define M 50001

typedef long long LL;

LL pos[N][M],last[M];

struct node
{
    int x,y;
}e[N];

int h[N];

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}

int main()
{
    int n,m,q;
    read(n); read(m); read(q);
    for(int i=1;i<=q;++i) 
    {
        read(e[i].x);
        read(e[i].y);
        h[i]=e[i].x;
    }
    sort(h+1,h+q+1);
    int tot=unique(h+1,h+q+1)-h-1;
    LL t;
    for(int i=1;i<=tot;++i)
    {
        t=(LL)(h[i]-1)*m;
        for(int j=1;j<=m;++j) pos[i][j]=++t;
    }
    for(int i=1;i<=n;++i) last[i]=last[i-1]+m;
    int nx;
    LL ans;
    for(int i=1;i<=q;++i)
    {
        nx=lower_bound(h+1,h+tot+1,e[i].x)-h;
        if(e[i].y==m) ans=last[h[nx]];
        else ans=pos[nx][e[i].y];
        cout<<ans<<'\n';
        if(e[i].y!=m)
        {
            for(int j=e[i].y;j<m-1;++j) pos[nx][j]=pos[nx][j+1];
            pos[nx][m-1]=last[h[nx]];
        }
        for(int j=h[nx];j<n;++j) last[j]=last[j+1];
        last[n]=ans;
    }
}
View Code

相关文章: