POJ 2828 Buy Tickets(线段树)

来源:互联网 发布:mac怎么玩英雄杀 编辑:程序博客网 时间:2024/06/14 08:57

题意:n个人排队,每个人有一个权值,给出他们插队的位置,求最后的顺序,按顺序输出权值。

解:逆着想,最后一个人插队后, 他的位置就是确定了下来的。倒数第二个人插的话,位置在最后一个的前面,最后一个对他无影响,位置在最后一个后面,则最后一个对他有影响,他必须往后移一位。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxm=2e5+10;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int sum[maxm<<2];int add[maxm<<2];int a[maxm<<2],b[maxm<<2];void pushdown(int rt){    sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){    if(l==r)    {        sum[rt]=1;        return;    }    int m=(l+r)>>1;    build(lson);    build(rson);    pushdown(rt);}void updata(int L,int c,int l,int r,int rt){    if(l==r)    {        add[r]=c;        sum[rt]-=1;        return;    }    int m=(l+r)>>1;    if(L<=sum[rt<<1])        updata(L,c,lson);    else        updata(L-sum[rt<<1],c,rson);    pushdown(rt);}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        build(1,n,1);        for(int i=1; i<=n; i++)        {            scanf("%d%d",&a[i],&b[i]);            a[i]++;        }        for(int i=n;i>=1;i--)        {            updata(a[i],b[i],1,n,1);        }        for(int i=1; i<=n; i++)        {            if(i==1)                printf("%d",add[i]);            else                printf(" %d",add[i]);        }        printf("\n");    }    return 0;}

1 0
原创粉丝点击