5478. [NOIP2017 improve group match official parade]

Title Description

Sylvia is a girl's love of learning.
Some time ago, Sylvia attended the school of military training. As we all know, when the military need to stand square. Sylvia square where there are students n × m, the number of matrix rows is n, the number of columns is m.
For ease of administration, at the beginning of the training instructors, according to front to back, in order from the left to the square from 1 to n × m compiled on the number (see examples below). Namely: the initial i-th row j-th column of the student number is (i - 1) × m + j.
However, in practice, when the square, because students often have a variety of things to leave. In a day, a total of q pieces happened to leave such an event. Each event can leave with a number of (y, z) (1≤x≤n, 1≤y≤m) description, x represents the row y column of students leaving the team.
After the students leave, the team there is a vacancy. To neat team, such instructors in turn issued two instructions:
1. dress to the left. Then the first column to remain intact, all the students to fill the gap left. After difficult to find this instruction, gap x m-th column in the first row.
2. look ahead together. Then the first line to remain intact, all the students to fill the vacancy forward. After difficult to find this instruction, the first gap in the n-th row and m columns.
Instructors provisions can not have two or more students at the same time leaving the team. That left the band after a student rejoin former student next to leave. Therefore, when each of the students to leave a rejoin, and only the ranks of the m-th column n-th row a gap, then naturally the student to fill this position.
Because the station square is really boring, so Sylvia wants to leave is calculated every event, the number of students leaving the team is.
Note: Each student numbers will not leave with the occurrence of an event of change, leaving the team after the incident in the square number of students may be out of order.

Topic analysis

The difficult questions.
However, we found that the whole process can be summarized in two modes of operation:
1. Identify the number of k from the sequence and delete.
2. Delete the sequence number added to the back.
So we can use n + 1 Ke tree line to resolve.
The first n row trees are maintained for each column of the first to m-1 columns of
n + 1-m-tree maintenance column.
The key is: 300,000 * 300,000 Zezheng?
It can only be opened with a dynamic point to resolve.
How to dynamically open point? Own look at the code the way to learn it.

Code

#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long ll;
struct node
{
    int x,y;
}a[310000];
struct tree
{
    int lc,rc;ll c;
}tr[6100000];int tail[310000],root[310000];
int tot=0;int size[6100000];
void insert(int &now,int l,int r,int k,ll num)
{
    if(now==0) now=++tot;
    if(l==r)
    {
        tr[now].c=num;
        size[now]=0;
        return ;
    }
    int mid=(l+r)/2;
    if(k<=mid) insert(tr[now].lc,l,mid,k,num);
    else insert(tr[now].rc,mid+1,r,k,num);
    size[now]=size[tr[now].lc]+size[tr[now].rc];
}
ll findkth(int &now,int l,int r,int k,int &ans)
{
    if(now==0) now=++tot;
    if(l==r)
    {
        ans=l;
        ll temp=tr[now].c;tr[now].c=0;
        size[now]=1;
        return temp;
    }
    int mid=(l+r)/2;ll temp;
    if(mid-l+1-size[tr[now].lc]>=k)
    {
        temp=findkth(tr[now].lc,l,mid,k,ans);
    }
    else
    {
        temp=findkth(tr[now].rc,mid+1,r,k-(mid-l+1-size[tr[now].lc]),ans);
    }
    size[now]=size[tr[now].lc]+size[tr[now].rc];
    return temp;
}
int main()
{
    ll n,m,q;
    scanf("%lld%lld%lld",&n,&m,&q);
    for(int i=1;i<=n;i++) tail[i]=m-1;
    tail[n+1]=n;
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].y);
        if(a[i].y==m)
        {
            int temp2;
            ll temp=findkth(root[n+1],1,n+q,a[i].x,temp2);
            if(temp2<=n) temp=temp2*m;
            printf("%lld\n",temp);
            insert(root[n+1],1,n+q,++tail[n+1],temp);
        }
        else
        {
            int temp2;
            ll temp=findkth(root[a[i].x],1,m+q,a[i].y,temp2);
            if(temp2<m) temp=m*(a[i].x-1)+temp2;
            printf("%lld\n",temp);
            insert(root[n+1],1,n+q,++tail[n+1],temp);
            temp=findkth(root[n+1],1,n+q,a[i].x,temp2);
            if(temp2<=n) temp=temp2*m;
            insert(root[a[i].x],1,m+q,++tail[a[i].x],temp);
        }
    }
    return 0;
}
Published 58 original articles · won praise 12 · views 8581

Guess you like

Origin blog.csdn.net/fengqiyuka/article/details/78635585