poj2828 Buy Tickets - Reverse order processing

Subject: http://poj.org/problem?id=2828

This question can be done in reverse order, because the later the person actually has the higher priority;

Use 0 and 1 to indicate whether there is already someone at this position, 0 means yes, 1 means no, so the tree array maintains the prefix sum to indicate how many empty positions there are in front of this position;

Every time a person is inserted, find the position where the number of empty positions in front is exactly the number he requires, which is the position where he finally stands (if the position is not empty, it means that the person behind him has jumped in front of him, so he is pushed to the back. );

After finding the position, assign the value of the position to 0, indicating that there is also a person standing here, and it can be processed backwards.

code show as below:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const MAXN=200005;
int n,val[MAXN],f[MAXN],x[MAXN],pos[MAXN];
int query(int x)
{
    int s=0;
    for(;x;x-=(x&-x))
        s+=f[x];
    return s;
}
void add(int x,int w)
{
    for(;x<=n;x+=(x&-x))
        f[x]+=w;
}
intmain ()
{
    while(scanf("%d",&n)==1)
    {
        memset(pos,0,sizeof pos);
        for(int i=1;i<=n;i++)add(i,1);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&x[i],&val[i]);
        for(int i=n;i;i--)
        {
            int l=1,r=n,p;
            while(l<=r)
            {
                int mid=((l+r)>>1);
                if(query(mid)>=x[i]+1)p=mid,r=mid-1;
                else l=mid+1;
            }
            pos[p]=i;
            add(p,-1);
        }
        for(int i=1;i<=n;i++)
            printf("%d ",val[pos[i]]);
        printf("\n");
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325016643&siteId=291194637