标签:codeforces dp
题意:
n(10^5)个数字的序列a 求每个位置i 它是不出现在任何LIS中 还是 出现在一些LIS中 还是 出现在所有LIS中
思路:
比赛时候唯一没做出的题… 赛后还是不会做… - -b 看了别人的代码觉得好精妙!!
首先以O(nlogn)复杂度求出LIS
然后我们倒序扫描序列a 对于位置i 如果lis[i]=LIS或者a[i]<big[lis[i]+1] (big[x]表示lis=x的a的最大值 这里的意思是 如果a[i]是某个LIS的最后一个 或者 能与某个LIS想接) 那么这个位置是出现在LIS中的 它是不是必经之路呢?? 我们在记录一个num[y] 表示lis=y的且出现在LIS中的位置的个数
最后 我们判断如果不出现在LIS中则分到1组 否则 如果num[lis[i]]=1说明它是毕竟之路(没有与它并列的位置) 分到3组 否则 到2组
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<map> #include<set> #include<vector> #include<queue> #include<cstdlib> #include<ctime> #include<cmath> using namespace std; typedef long long LL; #define N 100010 int n; int a[N], lis[N], st[N], top, in[N], big[N], num[N]; int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); top = 1; for (int i = 1; i <= n; i++) { if (st[top - 1] < a[i]) { st[top] = a[i]; lis[i] = top; top++; } else { int pos = lower_bound(st + 1, st + top, a[i]) - st; st[pos] = a[i]; lis[i] = pos; } } top--; for (int i = n; i >= 1; i--) { if (lis[i] == top || big[lis[i] + 1] > a[i]) { in[i] = 1; num[lis[i]]++; big[lis[i]] = max(big[lis[i]], a[i]); } } for (int i = 1; i <= n; i++) { if (in[i]) { if (num[lis[i]] > 1) putchar('2'); else putchar('3'); } else putchar('1'); } return 0; }
CodeForces 486E LIS of Sequence
标签:codeforces dp
原文地址:http://blog.csdn.net/houserabbit/article/details/41358473