感觉这道题用单调栈做这一点还是很容易看出来的。
然后我们就会发现其实现在问题变得非常的简单。
每次读入一个数,就找到第一个比它小的数并进行替换,然后将前面的数全部删掉就可以了,处理每一个数的时候都要更新一下答案。 附一下代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long n,top;
long long Ans;
int a[500050],stk[500050];
void dfs(int x)
{
int le=0,ri=top,mid,ret=0;
while(le<=ri)
{
mid=(le+ri)>>1;
if(a[stk[mid]]>x)ret=mid,le=mid+1;
else ri=mid-1;
}
if(!ret)Ans+=top;
else Ans+=top-ret+1;
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
for(int i=1; i<=n; ++i)
{
dfs(a[i]);
while(top>0&&a[i]>a[stk[top]])--top;
stk[++top]=i;
}
printf("%lld",Ans);
return 0;
}