SPOJ 057 Supernumbers in a permutation

  原题链接:http://www.spoj.com/problems/SUPPER/

  这道题n<=200000,那么确定为nlogn的算法,再定位到求LIS的O(nlogn)的算法。

  对于每个a[i],求出其向左能延伸的元素个数L[i]和向右能延伸的元素个数R[i],所有位置L[i]+R[i]为最大值的元素排序输出即可。

  心得:

  1.求LIS的O(nlogn)算法能解决子区间的LIS问题,所以经常出现在题目中,要灵活运用。

  2.lower_bound函数有cmp函数参数可以选择升序查找(less<int>())或降序查找(greater<int>())。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <vector>
 5 #include <queue>
 6 using namespace std;
 7 
 8 #define N 100005
 9 
10 int a[N], L[N], R[N], n, m, d[N];
11 vector<int> vt;
12 
13 int main()
14 {
15     for(int cas = 1; cas <= 10; cas++)
16     {
17         scanf("%d", &n);
18         for(int i = 0; i < n; i++)
19             scanf("%d", &a[i]);
20         vt.clear();
21         for(int i = 0; i < n; i++)
22         {
23             int j = lower_bound(vt.begin(), vt.end(), a[i], less<int>()) - vt.begin();
24             if(j == vt.size())
25                 vt.push_back(a[i]);
26             else
27                 vt[j] = min(vt[j], a[i]);
28             L[i] = j;
29         }
30         vt.clear();
31         for(int i = n - 1; i >= 0; i--)
32         {
33             int j = lower_bound(vt.begin(), vt.end(), a[i], greater<int>()) - vt.begin();
34             if(j == vt.size())
35                 vt.push_back(a[i]);
36             else
37                 vt[j] = max(vt[j], a[i]);
38             R[i] = j;
39         }
40         m = 0;
41         for(int i = 0; i < n; i++)
42             if(L[i] + R[i] > m) m = L[i] + R[i];
43         int k(0);
44         for(int i = 0; i < n; i++)
45         {
46             if(L[i]+R[i] == m)
47             {
48                 d[k++] = a[i];
49             }
50         }
51         sort(d, d+k);
52         printf("%d\n", k);
53         for(int i = 0; i < k; i++)
54         {
55             if(i != 0) putchar(' ');
56             printf("%d", d[i]);
57         }
58         putchar('\n');
59     }
60     return 0;
61 }
View Code

 

 

 

posted @ 2013-11-01 17:41  芒果布丁  阅读(235)  评论(0编辑  收藏  举报