线段树+逆序插入。
1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAXN 200005 5 #define lson l, mid, rt<<1 6 #define rson mid+1, r, rt<<1|1 7 8 int space[MAXN<<2]; 9 int nums[MAXN]; 10 int pi[MAXN], vi[MAXN]; 11 int pos; 12 13 void build(int l, int r, int rt) { 14 int mid; 15 space[rt] = r - l +1; 16 if (l == r) 17 return ; 18 mid = (l+r)>>1; 19 build(lson); 20 build(rson); 21 } 22 23 void update(int p, int l, int r, int rt) { 24 int mid; 25 --space[rt]; 26 if (l == r) { 27 pos = l; 28 return ; 29 } 30 mid = (l+r) >> 1; 31 if (space[rt<<1] >= p) 32 update(p, lson); 33 else { 34 p -= space[rt<<1]; 35 update(p, rson); 36 } 37 } 38 39 int main() { 40 int i, n; 41 42 while (scanf("%d", &n) != EOF) { 43 build(1, n, 1); 44 for (i=1; i<=n; ++i) 45 scanf("%d %d", &pi[i], &vi[i]); 46 for (i=n; i>0; --i) { 47 update(pi[i]+1, 1, n, 1); 48 nums[pos] = vi[i]; 49 //printf("pos=%d ", pos); 50 } 51 printf("%d", nums[1]); 52 for (i=2; i<=n; ++i) 53 printf(" %d", nums[i]); 54 printf(" "); 55 } 56 57 return 0; 58 }