1 条题解
-
0
自动搬运
来自洛谷,原作者为

Alex_Wei
**搬运于
2025-08-24 22:21:25,当前版本为作者最后更新于2020-08-23 14:13:26,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意简述:给出 和 ,求
$$\sum_{i=1}^n\sum_{j=i}^n\left(\max_{i\leq k\leq j}a_k-\min_{i\leq k\leq j}a_k\right) $$
提供一个不一样的思路。
我们设 为以 结尾的所有子序列的最大 / 最小值之和,那么答案为 。
考虑如何维护 。
不妨设 为满足 的最大的 (特别的,如果 不存在则为 ),那么有转移方程 , 可以用单调栈维护。
稍微解释一下上面的转移方程是如何得来的:
- 因为 对 以及 以前的最大值没有影响(即 与 , 与 与 的最大值相同),所以可以直接由 转移得来。
- 而根据 的定义,后面 个子序列(即 )的最大值为 ,所以加上 。
- 所以转移方程为 。
维护 只需要将 的定义中「」改为「」即可,用两个单调栈即可求出答案。
时间复杂度 ,常数较小,代码好写,而且跑得飞快,甚至抢到了最优解(2020.8.23)。
const int N=3e5+5; ll n,t1,t2,ans,f[N],g[N]; pii a[N],b[N]; int main(){ n=read(); for(int i=1;i<=n;i++){ ll x=read(),p; while(t1&&x>=a[t1].fi)t1--; while(t2&&x<=b[t2].fi)t2--; p=a[t1].se; f[i]=f[p]+x*(i-p); p=b[t2].se; g[i]=g[p]+x*(i-p); ans+=f[i]-g[i],a[++t1]=b[++t2]={x,i}; } cout<<ans<<endl; return 0; }
- 1
信息
- ID
- 5530
- 时间
- 1000ms
- 内存
- 64MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者