首页 > 代码库 > poj2828--Buy Tickets

poj2828--Buy Tickets

题意 :总共n个人,一个一个的来排队,每个人都有一个要求,要求排到第几个人后面(当然肯定是最后面来的人的要求先满足),每个人有一个对应的val,按顺序输出n的人的val。

用线段树来维护区间剩余的位置数量,,当然必须从最后一个人向前来更新线段树,每次更新之后就把该位置的剩余数量置为0(因为后面的人的要求肯定最先满足嘛)

代码如下:

#include <set>#include <map>#include <cmath>#include <ctime>#include <queue>#include <stack>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef unsigned long long ull;typedef long long ll;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const int maxn = 2e5+10;int seg[maxn<<2],ans[maxn],Pos[maxn],val[maxn],n;void build(int l,int r,int pos){    if (l == r)    {        seg[pos] = 1;        return;    }    int mid = (l + r) >> 1;    build(l,mid,pos<<1);    build(mid+1,r,pos<<1|1);    seg[pos] = seg[pos<<1] + seg[pos<<1|1];}int update(int l,int r,int pos,int x){    if (l == r)    {        seg[pos] = 0;        return l;    }    int mid = (l + r) >> 1;    int ans;    if (seg[pos<<1] >= x)        ans = update(l,mid,pos<<1,x);    else        ans = update(mid+1,r,pos<<1|1,x-seg[pos<<1]);    seg[pos] = seg[pos<<1|1] + seg[pos<<1];    return ans;}int main(void){    #ifndef ONLINE_JUDGE        freopen("in.txt","r",stdin);    #endif    while (~scanf ("%d",&n))	{	  for (int i = 0; i < n; i++)      {          scanf ("%d%d",Pos+i,val+i);      }      build(1,n,1);      for (int i = n - 1; i >= 0; i--)      {          int tmp = update(1,n,1,Pos[i]+1);          ans[tmp-1] = val[i];      }      printf("%d",ans[0]);      for (int i = 1; i < n; i++)      {          printf(" %d",ans[i]);      }      printf("\n");	}	return 0;}

  

poj2828--Buy Tickets