poj 2828 Buy Tickets

来源:互联网 发布:什么写作软件好 编辑:程序博客网 时间:2024/06/08 04:40

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


思路:将输入数据逆序传入,pos[i]表示此时这个人前面应有多少个空位。所以就用线段树来维护某个区间内的空位个数。在查找操作时如果t[rt<<1]<=target,就将target减去t[rt<<1],在右子树中找,最终定位在target==0且l==r的位置。


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <stack>#include <queue>#define fi first#define se second#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1using namespace std;typedef long long LL;typedef pair<int, int> P;//headconst int MAX = 2e5+5;P q[MAX];int t[MAX<<2];int ans[MAX];void pushUp(int rt){    t[rt] = t[rt<<1] + t[rt<<1|1];}void build(int l, int r, int rt){    if(l==r)    {        t[rt] = 1;        return;    }    int m = (l+r)>>1;    build(lson);    build(rson);    pushUp(rt);}void update(int pos, int l, int r, int rt){    if(l==r)    {        t[rt]--;        return;    }    int m = (l+r)>>1;    if(pos<=m)        update(pos, lson);    else        update(pos, rson);    pushUp(rt);}int query(int target, int l, int r, int rt)//return the position to add the entry{    if(l==r && target==0)        return r;    int m = (l+r)>>1;    if(t[rt<<1]<=target)        return query(target-t[rt<<1], rson);    else        return query(target, lson);}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        build(1,n,1);        for(int i=1; i<=n; i++)            scanf("%d%d",&q[i].fi,&q[i].se);        for(int i=n; i>=1; i--)        {            int pos = query(q[i].fi, 1, n, 1);            ans[pos] = q[i].se;            update(pos, 1, n, 1);        }        for(int i=1; i<n; i++)            printf("%d ",ans[i]);        printf("%d\n",ans[n]);    }    return 0;}
0 0
原创粉丝点击