标签:
下午比赛的时候写搓了,晚上重写一次就过了,o(╯□╰)o。
思路:按照字典序贪心,用线段树来维护区间最值,用set来维护求出答案的封闭区间。
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <set> 7 using namespace std; 8 9 const int N = 100001; 10 int a[N]; 11 int pos[N]; 12 int ans[N]; 13 bool visit[N]; 14 set<int> s; 15 set<int>::iterator it; 16 17 struct Node 18 { 19 int l, r, maxn; 20 } node[N << 2]; 21 22 void pushup( int i ) 23 { 24 node[i].maxn = max( node[i << 1].maxn, node[i << 1 | 1].maxn ); 25 } 26 27 void build( int i, int l, int r ) 28 { 29 node[i].l = l, node[i].r = r; 30 if ( l == r ) 31 { 32 node[i].maxn = a[l]; 33 return ; 34 } 35 int mid = ( l + r ) >> 1; 36 build( i << 1, l, mid ); 37 build( i << 1 | 1, mid + 1, r ); 38 pushup(i); 39 } 40 41 void update( int i, int pos, int val ) 42 { 43 if ( node[i].l == pos && node[i].r == pos ) 44 { 45 node[i].maxn = val; 46 return ; 47 } 48 int mid = ( node[i].l + node[i].r ) >> 1; 49 if ( pos <= mid ) 50 { 51 update( i << 1, pos, val ); 52 } 53 else 54 { 55 update( i << 1 | 1, pos, val ); 56 } 57 pushup(i); 58 } 59 60 int query( int i, int l, int r ) 61 { 62 if ( node[i].l == l && node[i].r == r ) 63 { 64 return node[i].maxn; 65 } 66 int mid = ( node[i].l + node[i].r ) >> 1; 67 if ( r <= mid ) 68 { 69 return query( i << 1, l, r ); 70 } 71 else if ( l > mid ) 72 { 73 return query( i << 1 | 1, l, r ); 74 } 75 else 76 { 77 return max( query( i << 1, l, mid ), query( i << 1 | 1, mid + 1, r ) ); 78 } 79 } 80 81 int main () 82 { 83 int t; 84 scanf("%d", &t); 85 while ( t-- ) 86 { 87 int n; 88 scanf("%d", &n); 89 for ( int i = 1; i <= n; i++ ) 90 { 91 scanf("%d", &a[i]); 92 pos[a[i]] = i; 93 } 94 memset( ans, -1, sizeof(ans) ); 95 memset( visit, 0, sizeof(visit) ); 96 build( 1, 1, n ); 97 s.clear(); 98 for ( int i = 1; i <= n; i++ ) 99 { 100 if ( ans[i] != -1 ) continue; 101 int start = 1; 102 if ( !s.empty() ) 103 { 104 it = s.upper_bound(pos[i]); 105 if ( it != s.begin() ) 106 { 107 it--; 108 start = (*it); 109 start++; 110 } 111 } 112 int tmp = query( 1, start, pos[i] ); 113 if ( pos[i] != n && !visit[a[pos[i] + 1]] && tmp < a[pos[i] + 1] ) 114 { 115 ans[i] = a[pos[i] + 1]; 116 update( 1, pos[i] + 1, -1 ); 117 } 118 else 119 { 120 ans[i] = tmp; 121 visit[tmp] = true; 122 for ( int j = pos[tmp]; j < pos[i]; j++ ) 123 { 124 ans[a[j]] = a[j + 1]; 125 } 126 s.insert(pos[i]); 127 } 128 } 129 for ( int i = 1; i < n; i++ ) 130 { 131 printf("%d ", ans[i]); 132 } 133 printf("%d\n", ans[n]); 134 } 135 return 0; 136 }
标签:
原文地址:http://www.cnblogs.com/huoxiayu/p/4690373.html