#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+5;
ll n;
ll a[N];
stack <int> stk;
int lmax[N],rmax[N],lmin[N],rmin[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
//预处理第一个小于/大于a[i]的元素的前一个和最后一个小于/大于a[i]的元素的后一个的位置
while(!stk.empty())
stk.pop();
for(int i=1;i<=n;i++)
{
while(!stk.empty() && a[stk.top()]<=a[i])
stk.pop();
if(stk.empty())
lmax[i]=0;
else
lmax[i]=stk.top();
stk.push(i);
}
while(!stk.empty())
stk.pop();
for(int i=1;i<=n;i++)
{
while(!stk.empty() && a[stk.top()]>=a[i])
stk.pop();
if(stk.empty())
lmin[i]=0;
else
lmin[i]=stk.top();
stk.push(i);
}
while(!stk.empty())
stk.pop();
for(int i=n;i>=1;i--)
{
while(!stk.empty() && a[stk.top()]<a[i])
stk.pop();
if(stk.empty())
rmax[i]=n+1;
else
rmax[i]=stk.top();
stk.push(i);
}
while(!stk.empty())
stk.pop();
for(int i=n;i>=1;i--)
{
while(!stk.empty() && a[stk.top()]>a[i])
stk.pop();
if(stk.empty())
rmin[i]=n+1;
else
rmin[i]=stk.top();
stk.push(i);
}
ll ans=0;
for(int i=1;i<=n;i++)
{
ans=ans+a[i]*(i-lmax[i])*(rmax[i]-i);
ans=ans-a[i]*(i-lmin[i])*(rmin[i]-i);
}
cout<<ans;
return 0;
}
这份代码是AC的。在第75和76行都有一个 a[i] 参与了乘法,但如果把 a[i] 挪到后面再乘就只有40分了,就像这样
ans=ans+(i-firstmore[i])*(lastmore[i]-i)*a[i];
ans=ans-(i-firstless[i])*(lastless[i]-i)*a[i];
有人可以解释是为什么吗