51nod 2478单调栈前缀和小b接水
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 2478单调栈前缀和小b接水相关的知识,希望对你有一定的参考价值。
题目
输入样例
12
0 1 0 2 1 0 1 3 2 1 2 1
输出样例
6
解题思路
可以发现最后能拦住水的都是向两边递减高度(?)
不管两个高积木之间的的积木是怎样乱七八糟的高度,最后能用来装水的还是那两个积木
先找到最高的那个积木,从中间向两边分别做单调栈
距离乘高很容易,怎么减去中间的积木体积?
!前缀和
Code
#include <bits/stdc++.h>
#define ll long long
#define N 50000
using namespace std;
ll n, ans, top, max_num, max_id, a[N + 100], s[N + 100], q[N + 100];
int main()
scanf("%lld", &n);
for(int i = 1; i <= n; i ++)
scanf("%lld", &a[i]);
s[i] = s[i - 1] + a[i]; //前缀和
if(a[i] > max_num) //找最高的积木
max_num =a[i];
max_id = i;
q[++ top] = max_id; //左边
for(int i = max_id - 1; i; i --)
while(top && a[q[top]] < a[i]) top --;
q[++ top] = i;
while(top > 1)
ans += a[q[top]] * (q[top - 1] - q[top] - 1) - (s[q[top - 1] - 1] - s[q[top]]);
top --;
//***************************************************
for(int i = max_id + 1; i <= n; i ++) //右边
while(top && a[q[top]] < a[i]) top --;
q[++ top] = i;
while(top > 1)
ans += a[q[top]] * (q[top] - q[top - 1] - 1) - (s[q[top] - 1] - s[q[top - 1]]);
top --;
printf("%lld", ans);
以上是关于51nod 2478单调栈前缀和小b接水的主要内容,如果未能解决你的问题,请参考以下文章
51nod 1102 面积最大的矩形 && 新疆大学OJ 1387: B.HUAWEI's billboard 单调栈+拼凑段(o(n) 或 o(nlog(n))