題解
首先對於區間 來說,若 .
則 的貢獻就是跨過點的區間個數.
即.
此處的 用ST表求解。
然後分治區間和區間即可。
代碼如下:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100000;
int n, ans = 0;
int a[N], f[N][30];
void init(void)
{
for (int i=1;i<=n;++i) f[i][0] = i;
int t = log2(n);
for (int j=1;j<=t;++j)
for (int i=1;i<=n-(1<<j)+1;++i)
{
if (a[f[i][j-1]] < a[f[i+(1<<j-1)][j-1]])
f[i][j] = f[i+(1<<j-1)][j-1];
else f[i][j] = f[i][j-1];
}
return;
}
int find_max(int l,int r)
{
int k = log2(r-l+1);
if (a[f[l][k]] < a[f[r-(1<<k)+1][k]])
return f[r-(1<<k)+1][k];
return f[l][k];
}
void dfs(int l,int r)
{
if (l > r) return;
int x = find_max(l,r);
ans += a[x]*(x-l+1)*(r-x+1);
dfs(l,x-1);
dfs(x+1,r);
return;
}
signed main(void)
{
cin>>n;
for (int i=1;i<=n;++i)
scanf("%lld", a+i);
init();
dfs(1,n);
cout<<ans<<endl;
return 0;
}