POJ2828 Buy Tickets

题目大意

有n个陆续去售票口排队买票,每个人都会插队,第i个人会插到位置为pos[i]的人的后面,问最后队列的情况

题解

我们可以发现,对于第n个人,它插入的位置就是他最终站的位置,因此我们从第n个人开始处理,对于第i个人,找到第pos[i]+1个空位插入即可,然后空位减少一个,查找空位和对空位数量进行修改刚好可以用线段树来处理

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define lson l, m , s << 1
#define rson m + 1 , r , s << 1 | 1
#define MAXN 200005
using namespace std;
int val[MAXN<<2],pos[MAXN<<2],sumv[MAXN<<2],ans[MAXN],t;
void build(int l,int r,int s)
{
    sumv[s]=r-l+1;
    if(l==r)
        return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}
void update(int p,int l,int r,int s)
{
    sumv[s]--;
    if(l==r)
    {
        t=l;
        return;
    }
    int m=(l+r)>>1;
    if(p<=sumv[s<<1]) update(p,lson);
    else update(p-sumv[s<<1],rson);
}
int main(void)
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        build(1,n,1);
        for(int i=1; i<=n; i++)
            scanf("%d%d",&pos[i],&val[i]);
        for(int i=n; i>=1; i--)
        {
            update(pos[i]+1,1,n,1);
            ans[t]=val[i];
        }
        for(int i=1; i<n; i++)
            printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zjbztianya/p/3076537.html