题意:给出一个数列,判断每个数:
1:不在任何lis中
2:在lis中,但不在所有的lis中(就是lis不一定要经过他)
3:在所有lis中
思路:
对于1,前后各跑一遍,然后记录一下以它开始(到它结束)的lis长度,若开始和结束的两个长度和<len+1(len为数列lis长度),则为1(应该很显然)
对于3,记录所有不是1情况的数以它开始的lis长度,若一个长度出现>=1次,那么所有为这种长度的数均不是必经过的数(就是为2),否则为1(似乎也蛮明显)
然后就好了。。
代码:
#include <bits/stdc++.h>
#define N 100009
using namespace std;
int n,m,a[N],Stack[N],top,x,now[N],Now[N],Ans;
int pd[N];
char b[N];
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
Stack[++top]=a[n];
now[n]=1;
for (int i=n-1;i>=1;i--)
{
if (a[i]<Stack[top]) Stack[++top]=a[i],now[i]=top;
else
{
int l=1,r=top,ans=0;
while (l<=r)
{
int mid=l+r>>1;
if (Stack[mid]>a[i]) ans=mid,l=mid+1;
else r=mid-1;
}
Stack[ans+1]=a[i];
now[i]=ans+1;
}
}
Ans=top;
top=0;
Stack[++top]=a[1];
Now[1]=1;
for (int i=2;i<=n;i++)
{
if (a[i]>Stack[top]) Stack[++top]=a[i],Now[i]=top;
else
{
int l=1,r=top,ans=0;
while (l<=r)
{
int mid=l+r>>1;
if (Stack[mid]>=a[i]) ans=mid,r=mid-1;
else l=mid+1;
}
Stack[ans]=a[i];
Now[i]=ans;
}
}
for (int i=1;i<=n;i++)
if (now[i]+Now[i]<Ans+1) b[i]=49;
else b[i]=50,pd[Now[i]]++;
for (int i=1;i<=n;i++)
if (b[i]==50&&pd[Now[i]]==1) b[i]++;
b[n+1]='\0';
puts(b+1);
return 0;
}