2014-10-01 20:44:42
思路:倒着考虑,比如现在考虑到了第 k 个,他要排到第 p 个位置,那么一定要让他前面有 p-1 个空位,用线段树维护即可,每个节点存这段区间内空位个数。、
1 /************************************************************************* 2 > File Name: 2828.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Wed 01 Oct 2014 05:50:31 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <queue> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 #define lpos (pos << 1) 18 #define rpos (pos << 1|1) 19 #define getmid(l,r) (l + (r - l) / 2) 20 typedef long long ll; 21 const int INF = 1 << 30; 22 const int maxn = 200010; 23 24 int N; 25 int ans[maxn]; 26 27 struct node{ 28 int val,num; 29 }t[maxn << 2]; 30 31 void Build_tree(int pos,int l,int r){ 32 t[pos].num = r - l + 1; 33 if(l == r) 34 return; 35 int mid = getmid(l,r); 36 Build_tree(lpos,l,mid); 37 Build_tree(rpos,mid + 1,r); 38 } 39 40 void Update(int p,int v,int pos,int l,int r){ 41 if(l == r){ 42 ans[l] = v; 43 t[pos].val = v; 44 t[pos].num = 0; 45 return; 46 } 47 int mid = getmid(l,r); 48 if(t[lpos].num >= p){ 49 Update(p,v,lpos,l,mid); 50 } 51 else{ 52 Update(p - t[lpos].num,v,rpos,mid + 1,r); 53 } 54 t[pos].num--; 55 } 56 57 int main(){ 58 int p[maxn],v[maxn]; 59 while(~scanf("%d",&N)){ 60 Build_tree(1,1,N); 61 for(int i = N; i >= 1; --i) 62 scanf("%d%d",&p[i],&v[i]); 63 for(int i = 1; i <= N; ++i) 64 Update(p[i] + 1,v[i],1,1,N); 65 for(int i = 1; i <= N; ++i){ 66 if(i != 1) printf(" "); 67 printf("%d",ans[i]); 68 } 69 puts(""); 70 } 71 return 0; 72 }