D. Imbalanced Array

让你计算所有连续子序列的最大值-最小值的和。

 (单调栈)

对于一个数Ai来讲,如果其有贡献的价值,要么是-Ai作为最小值,要么是Ai作为最大值。
那么Ans=ΣAi*maxn-Ai*minn.
void work()
{
    top=1,S[1]=P(N,0);
    F(i,1,n)
    {
        while(S[top].first<=a[i])top--;
        l[i]=S[top].second+1;
        S[++top]=P(a[i],i);
    }
    top=1,S[1]=P(N,n+1);
    for(int i=n;i;i--)
    {
        while(S[top].first<a[i])top--;
        r[i]=S[top].second-1;
        S[++top]=P(a[i],i);
    }
    F(i,1,n)ans+=1ll*a[i]*(i-l[i]+1)*(r[i]-i+1);
}

int main(){
    scanf("%d",&n);
    F(i,1,n)scanf("%d",a+i);
    work();
    F(i,1,n)a[i]*=-1;
    work();
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/planche/p/9428182.html