码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5338 线段树+stl+贪心

时间:2015-07-30 21:15:12      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:

下午比赛的时候写搓了,晚上重写一次就过了,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 }

 

hdu 5338 线段树+stl+贪心

标签:

原文地址:http://www.cnblogs.com/huoxiayu/p/4690373.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!