Codeforces Round #277 (Div. 2) E. LIS of Sequence DP
E. LIS of Sequence
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://codeforces.com/contest/486/problem/E
Description
The next "Data Structures and Algorithms" lesson will be about Longest Increasing Subsequence (LIS for short) of a sequence. For better understanding, Nam decided to learn it a few days before the lesson.
Nam created a sequence a consisting of n (1 ≤ n ≤ 105) elements a1, a2, ..., an (1 ≤ ai ≤ 105). A subsequence ai1, ai2, ..., aik where 1 ≤ i1 < i2 < ... < ik ≤ n is called increasing if ai1 < ai2 < ai3 < ... < aik. An increasing subsequence is called longest if it has maximum length among all increasing subsequences.
Nam realizes that a sequence may have several longest increasing subsequences. Hence, he divides all indexes i (1 ≤ i ≤ n), into three groups:
group of all i such that ai belongs to no longest increasing subsequences.
group of all i such that ai belongs to at least one but not every longest increasing subsequence.
group of all i such that ai belongs to every longest increasing subsequence.
Since the number of longest increasing subsequences of a may be very large, categorizing process is very difficult. Your task is to help him finish this job.
Nam created a sequence a consisting of n (1 ≤ n ≤ 105) elements a1, a2, ..., an (1 ≤ ai ≤ 105). A subsequence ai1, ai2, ..., aik where 1 ≤ i1 < i2 < ... < ik ≤ n is called increasing if ai1 < ai2 < ai3 < ... < aik. An increasing subsequence is called longest if it has maximum length among all increasing subsequences.
Nam realizes that a sequence may have several longest increasing subsequences. Hence, he divides all indexes i (1 ≤ i ≤ n), into three groups:
group of all i such that ai belongs to no longest increasing subsequences.
group of all i such that ai belongs to at least one but not every longest increasing subsequence.
group of all i such that ai belongs to every longest increasing subsequence.
Since the number of longest increasing subsequences of a may be very large, categorizing process is very difficult. Your task is to help him finish this job.
Input
The first line contains the single integer n (1 ≤ n ≤ 105) denoting the number of elements of sequence a.
The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 105).
Output
Print a string consisting of n characters. i-th character should be '1', '2' or '3' depending on which group among listed above index i belongs to.
Sample Input
4
1 3 2 5
Sample Output
3223
HINT
题意
给你n个数
然后问你这里面的每个数,是否是
1.不属于任何最长上升子序列中
2.属于多个最长上升子序列中
3.唯一属于一个最长上升子序列中
题解:
对于每一个数,维护两个dp
dp1表示1到i的最长上升子序列长度
dp2表示从n到i最长递减子序列长度
然后如果dp1[i]+dp2[i] - 1 == lis ,就说明属于lis里面,如果dp1[i]的值是唯一的,就说明唯一属于一个lis
否则就不属于咯
代码
#include<iostream> #include<stdio.h> #include<map> #include<cstring> #include<algorithm> using namespace std; #define maxn 100005 int b[maxn]; int a[maxn]; void add(int x,int val) { while(x<=100000) { b[x] = max(b[x],val); x += x & (-x); } } int get(int x) { int ans = 0; while(x) { ans = max(ans,b[x]); x -= x & (-x); } return ans; } int dp1[maxn]; int dp2[maxn]; int ans[maxn]; map<int,int> H; int main() { int n;scanf("%d",&n); int LIS = 0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); dp1[i] = 1 + get(a[i]-1); add(a[i],dp1[i]); LIS = max(LIS,dp1[i]); } reverse(a+1,a+1+n); memset(b,0,sizeof(b)); for(int i=1;i<=n;i++) { a[i] = 100000 - a[i] + 1; dp2[i] = 1 + get(a[i] - 1); add(a[i],dp2[i]); } reverse(dp2+1,dp2+1+n); for(int i=1;i<=n;i++) { if(dp1[i]+dp2[i]-1!=LIS)ans[i]=1; else H[dp1[i]]++; } for(int i=1;i<=n;i++) { if(ans[i]!=1&&H[dp1[i]]==1) { ans[i]=3; } } for(int i=1;i<=n;i++) if(ans[i]==1) cout<<"1"; else if(ans[i]==0) cout<<"2"; else if(ans[i]==3) cout<<"3"; } /* 10 2 2 2 17 8 9 10 17 10 5 */