Description
N<=10^5
Solution
显然,对于每一个ai,都必定从一个ak转移而来,并且k<i,ak=ai−1
那么xk<xi
因为我们要尽量让前面的x比后面的大,
所以每一个ai,对于一个aj=ai,j<i,要满足最优,都必须xj>xi,而本来是xj≥xi
所以对于任意一个i,它最优的k一定就是之前离它最近的一个。
那么k向i连边,显然构成一棵树。对于一个点转移出去的儿子,优先DFS遍历更靠后的点,那么它的DFS序就是该点的x<script type="math/tex" id="MathJax-Element-1546">x</script>了。
Code
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define N 100005
#define LL long long
using namespace std;
int n,m,a[N],l[N],d[N],lt[N],nt[N],dt[N],m1,x[N],v;
void dfs(int k)
{
x[k]=v++;
for(int i=lt[k];i;i=nt[i]) dfs(dt[i]);
}
void link(int x,int y)
{
nt[++m]=lt[x];
dt[lt[x]=m]=y;
}
int main()
{
cin>>n;
int m=0;
LL ans=0;
fo(i,1,n)
{
scanf("%d",&a[i]);
link(l[a[i]-1],i);
l[a[i]]=i;
}
dfs(0);
memset(d,107,sizeof(d));
d[0]=0;
fod(i,n,1)
{
int p=lower_bound(d,d+n+1,x[i])-d;
ans+=(LL)p;
d[p]=min(d[p],x[i]);
}
printf("%lld\n",ans);
}