// http://www.cnblogs.com/shenben/p/5624886.html
// 思路:根據題目可知,最後插入的位置的數纔是最終不變的數,
// 所以可以從最後的輸入作第1個放入,依此類推,倒插入。
// 在插入時也有一定的技術,首先創建一棵空線段樹時,每個節點
// 記錄當前範圍內有多少個空位置。在插入時,要注意,一個數放
// 入之後那麼這個位置就不用管了,那麼樹中所有的空位置就是餘
// 下的數所對應的位置,也就是把餘下的數又可以看作是一個新的
// 集合。那麼每次插入都是當前集合的第1次放。
#include<iostream>
#include<cstdio>
using namespace std;
const int N=200005;
int n,id,pos[N],val[N],ans[N],w[N*3];
void build(int k,int left,int right){
w[k]=right-left+1; // w記錄這個區間有多少的空位。
int mid=(left+right>>1);
if(left<right){
build(k<<1,left,mid);
build(k<<1|1,mid+1,right);
}
}
void updata(int k,int pos,int l,int r){
w[k]--;// 這個區間增加了一人,區間空位-1。
if(l==r){
id=l;return;
}
int mid=(l+r)/2;
if(w[k<<1]>=pos) updata(k<<1,pos,l,mid);
else{
pos-=w[k<<1];
updata(k<<1|1,pos,mid+1,r);
}
}
int main(){
freopen("a.txt","r",stdin);
while(scanf("%d",&n)==1){
build(1,1,n);
for(int i=1;i<=n;i++)
scanf("%d%d",&pos[i],&val[i]);
for(int i=n;i>=1;i--){
updata(1,pos[i]+1,1,n);
ans[id]=val[i];
}
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
putchar('\n');
}
return 0;
}
POJ2828 Buy Tickets(樹形DP)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.