CodeForces 486E LIS of Sequence

来源:互联网 发布:软件代理商协议 编辑:程序博客网 时间:2024/04/29 20:41

题意:

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 100010int 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');elseputchar('3');} elseputchar('1');}return 0;}


0 0
原创粉丝点击