单调栈搞一下,注意在等于时是否弹出。这里设为从左到右弹出,从右到左不弹出。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=50050;
long long a[MAXN],minlef[MAXN],minrig[MAXN],maxlef[MAXN],maxrig[MAXN];
struct node
{
int pos;
long long x;
}stk[MAXN];
int main()
{
long long n,i,ans,stknum;
while(~scanf("%lld",&n))
{
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
stknum=0;
for(i=1;i<=n;i++)
{
while(stknum&&stk[stknum-1].x>=a[i])
{
minrig[stk[stknum-1].pos]=i-1;
stknum--;
}
stk[stknum].pos=i;
stk[stknum].x=a[i];
stknum++;
}
while(stknum)
{
minrig[stk[stknum-1].pos]=n;
stknum--;
}
for(i=1;i<=n;i++)
{
while(stknum&&stk[stknum-1].x<=a[i])
{
maxrig[stk[stknum-1].pos]=i-1;
stknum--;
}
stk[stknum].pos=i;
stk[stknum].x=a[i];
stknum++;
}
while(stknum)
{
maxrig[stk[stknum-1].pos]=i-1;
stknum--;
}
for(i=n;i>=1;i--)
{
while(stknum&&stk[stknum-1].x>a[i])
{
minlef[stk[stknum-1].pos]=i+1;
stknum--;
}
stk[stknum].pos=i;
stk[stknum].x=a[i];
stknum++;
}
while(stknum)
{
minlef[stk[stknum-1].pos]=1;
stknum--;
}
for(i=n;i>=1;i--)
{
while(stknum&&stk[stknum-1].x<a[i])
{
maxlef[stk[stknum-1].pos]=i+1;
stknum--;
}
stk[stknum].pos=i;
stk[stknum].x=a[i];
stknum++;
}
while(stknum)
{
maxlef[stk[stknum-1].pos]=1;
stknum--;
}
ans=0;
for(i=1;i<=n;i++)
{
ans+=(i-maxlef[i]+1)*(maxrig[i]-i+1)*a[i];
ans-=(i-minlef[i]+1)*(minrig[i]-i+1)*a[i];
}
printf("%lld\n",ans);
}
}