1. 程式人生 > >poj2828 Buy Tickets——倒序處理

poj2828 Buy Tickets——倒序處理

esp == con 找到 AC div max poj2828 set

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

這題可以倒序來做,因為越靠後的人實際上優先級越高;

用0和1表示這個位置上是否已經有人,0表示有,1表示沒有,這樣樹狀數組維護前綴和表示這個位置前面有多少個空位置;

每插入一個人,找到前面空位置恰好是他要求的個數的那個位置,就是他最終站的位置(若位置不空則表示後面的人之後插隊到他前面了,所以他被擠到後面去);

找到位置後把該位置的值賦成0,表示這裏也站了人,倒著處理即可。

代碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using
namespace std; int const MAXN=200005; int n,val[MAXN],f[MAXN],x[MAXN],pos[MAXN]; int query(int x) { int s=0; for(;x;x-=(x&-x)) s+=f[x]; return s; } void add(int x,int w) { for(;x<=n;x+=(x&-x)) f[x]+=w; } int main() { while(scanf("%d",&n)==1) { memset(pos,
0,sizeof pos); for(int i=1;i<=n;i++)add(i,1); for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&val[i]); for(int i=n;i;i--) { int l=1,r=n,p; while(l<=r) { int mid=((l+r)>>1);
if(query(mid)>=x[i]+1)p=mid,r=mid-1; else l=mid+1; } pos[p]=i; add(p,-1); } for(int i=1;i<=n;i++) printf("%d ",val[pos[i]]); printf("\n"); } return 0; }

poj2828 Buy Tickets——倒序處理