让你计算所有连续子序列的最大值-最小值的和。
(单调栈)
对于一个数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; }