1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #define N 200010 5 #define lson p << 1 6 #define rson p << 1 | 1 7 using namespace std; 8 9 struct Nod 10 { 11 int l , r ; 12 int va ; // Gap 13 }node[N << 2]; 14 15 int pos[N] , val[N] , ans[N] ; 16 17 void build ( int l , int r , int p ) 18 { 19 node[p].l = l ; 20 node[p].r = r ; 21 node[p].va = r - l + 1 ; 22 if ( l == r) 23 return ; 24 int mid = ( l + r ) >> 1 ; 25 build ( l , mid , lson ) ; 26 build ( mid + 1 , r , rson ) ; 27 } 28 29 int update ( int ps , int p ) 30 { 31 node[p].va-- ; //Gap - 1 ; 32 if ( node[p].l == node[p].r ) { 33 return node[p].l ; //return the position of the insert 34 } 35 if ( node[lson].va >= ps ) { 36 update ( ps , lson ) ;//when lson‘s Gap equal to or greater than the insertion location , inserted to the left 37 } 38 else { 39 ps -= node[lson].va ;//when Gap on the left is less than the ps , insert the right side , the right of the insertion laction is 40 // ps minus Gap on the left 41 update ( ps , rson ) ; 42 } 43 } 44 45 int main () 46 { 47 //freopen ( "a.txt" , "r" , stdin ) ; 48 int n ; 49 while (~scanf ("%d" , &n ) ) { 50 build ( 1 , n , 1 ) ; 51 for ( int i = 1 ; i <= n ; i++ ) { 52 scanf ("%d%d" , pos + i , val + i ) ; 53 } 54 for ( int i = n ; i >= 1 ; i-- ) { 55 int id = update ( pos[i] + 1 , 1 ) ; // get the insert position 56 ans[id] = val[i] ; // in ans Array 57 } 58 for ( int i = 1 ; i < n ; i++ ) { 59 printf ( "%d " , ans[i] ) ; 60 } 61 printf ( "%d\n" , ans[n] ) ; 62 } 63 return 0 ; 64 }
集训时大神介绍了一种能节省空间的写法:
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #define N 200010 5 #define lson o << 1 , l , mid 6 #define rson o << 1 | 1 , mid + 1 , r 7 using namespace std; 8 9 int va[N << 2] ; // Gap 10 11 int pos[N] , val[N] , ans[N] ; 12 13 void build (int o , int l , int r ) 14 { 15 va[o] = r - l + 1 ; 16 if ( l == r ) 17 return ; 18 int mid = ( l + r ) >> 1 ; 19 build ( lson ) ; 20 build ( rson ) ; 21 } 22 23 int update ( int ps ,int o , int l , int r ) 24 { 25 va[o]-- ; //Gap - 1 ; 26 if ( l == r ) { 27 return l ; //return the position of the insert 28 } 29 int mid = ( l + r ) >> 1 ; 30 if ( va[o << 1] >= ps ) { 31 update ( ps , lson ) ;//when lson‘s Gap equal to or greater than the insertion location , inserted to the left 32 } 33 else { 34 ps -= va[o << 1] ;//when Gap on the left is less than the ps , insert the right side , the right of the insertion laction is 35 // ps minus Gap on the left 36 update ( ps , rson ) ; 37 } 38 } 39 40 int main () 41 { 42 //freopen ( "a.txt" , "r" , stdin ) ; 43 int n ; 44 while (~scanf ("%d" , &n ) ) { 45 build ( 1 , 1 , n ) ; 46 for ( int i = 1 ; i <= n ; i++ ) { 47 scanf ("%d%d" , pos + i , val + i ) ; 48 } 49 for ( int i = n ; i >= 1 ; i-- ) { 50 int id = update ( pos[i] + 1 , 1 , 1 , n ) ; // get the insert position 51 ans[id] = val[i] ; // in ans Array 52 } 53 for ( int i = 1 ; i < n ; i++ ) { 54 printf ( "%d " , ans[i] ) ; 55 } 56 printf ( "%d\n" , ans[n] ) ; 57 } 58 return 0 ; 59 }
原文:http://www.cnblogs.com/get-an-AC-everyday/p/4277339.html