POJ:2828 Buy Tickets(线段树)

来源:互联网 发布:智能电视软件市场 编辑:程序博客网 时间:2024/05/22 00:53

思路真的很奇妙。

从后往前,pos的意义是此时该人前面的空位。

这样用线段树寻找第k个元素即可。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <set>#include <map>#include <algorithm>#define ll  long long#define INF 2139062143#define inf -2139062144#define MOD 20071027#define MAXN  200005#define LEN 222222<<2using namespace std;int num[MAXN],val[MAXN],arr[MAXN];struct Segment_Tree{private :    int sum[LEN],sz;    void pushup(int o)    {        sum[o]=sum[o<<1]+sum[o<<1|1];    }    int myquery(int o,int L,int R,int v)    {        if(L==R)        {            sum[o]--;            return L;        }        int M=(L+R)>>1;        int p;        if(v<=sum[o<<1]) p=myquery(o<<1,L,M,v);        else  p=myquery(o<<1|1,M+1,R,v-sum[o<<1]);        pushup(o);        return p;    }public:    void init(int n)    {        sz=n;    }    void build(int o,int L,int R)    {        sum[o]=R-L+1;        if(L==R)  return ;        else        {            int M=(L+R)>>1;            build(o<<1,L,M);            build(o<<1|1,M+1,R);        }    }    int  query(int p)    {        return myquery(1,1,sz,p);    }};Segment_Tree tree;int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        for(int i=1; i<=n; ++i)            scanf("%d%d",&num[i],&val[i]);        tree.init(n);        tree.build(1,1,n);        for(int i=n; i>=1; --i)        {            int pos=tree.query(num[i]+1);            arr[pos]=val[i];        }        for(int i=1; i<=n; ++i)            if(i==1) printf("%d",arr[i]);            else printf(" %d",arr[i]);        printf("\n");    }    return 0;}


 

0 0
原创粉丝点击