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

Codeforces 486E LIS of Sequence 题解

时间:2016-12-18 14:30:57      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:长度   最长上升子序列   make   return   class   log   代码   ons   namespace   

题目大意:

  一个序列,问其中每一个元素是否为所有最长上升子序列中的元素或是几个但不是所有最长上升子序列中的元素或一个最长上升子序列都不是。

思路:

  求以每一个元素为开头和结尾的最长上升子序列长度,若两者相加比最长上升子序列长度+1小,则一个也不是;否则若有另一元素与它的两个值完全相同,则不是所有;否则在所有。

代码:

 1 #include<map>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 const int M=100009;
 6 map <pair<int,int>,int> mp;
 7 int i,n,top,a[M],st[M],f1[M],f2[M];
 8 bool flag[M];
 9 
10 void LIS(int *f)
11 {
12     st[top=1]=a[1]; f[1]=1;
13     for (int i=2;i<=n;++i)
14         if (st[top]<a[i]) st[++top]=a[i],f[i]=top;
15         else
16         {
17             int l=1,r=top,ans=0;
18             while (l<=r)
19             {
20                 int mid=l+r>>1;
21                 if (st[mid]<a[i]) ans=mid,l=mid+1; else r=mid-1;
22             }
23             st[ans+1]=a[i];
24             f[i]=ans+1;
25         }
26 }
27 
28 int main()
29 {
30     scanf("%d",&n);
31     for (i=1;i<=n;++i) scanf("%d",&a[i]);
32     LIS(f1);
33     for (i=1;i<=n;++i) a[i]=M-a[i];
34     for (i=1;i+i<=n;++i) swap(a[i],a[n+1-i]);
35     LIS(f2);
36     for (i=1;i+i<=n;++i) swap(f2[i],f2[n+1-i]);
37     ++top;
38     for (i=1;i<=n;++i)
39         if (f1[i]+f2[i]==top) ++mp[make_pair(f1[i],f2[i])];
40         else flag[i]=1;
41     for (i=1;i<=n;++i)
42         if (!flag[i])
43             if (mp[make_pair(f1[i],f2[i])]==1) printf("3");
44             else printf("2");
45         else printf("1");
46     return 0;
47 }

 

Codeforces 486E LIS of Sequence 题解

标签:长度   最长上升子序列   make   return   class   log   代码   ons   namespace   

原文地址:http://www.cnblogs.com/HHshy/p/6194059.html

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