单调栈的性质及应用

ZZULI  XXX

题意:给你一串序列,要你求所有子序列的最小值之和。(n很大,无法暴力)

思路:完美的单调栈模板

这里简要介绍下单调栈的性质,(其他的都没用)

单调栈的维护是 O(n) 级的时间复杂度,因为所有元素只会进入栈一次,并且出栈后再也不会进栈了。

单调栈的性质:

1.单调栈里的元素具有单调性

2.元素加入栈前,会在栈顶端把破坏栈单调性的元素都删除

3.使用单调栈可以找到元素向左遍历第一个比他小的元素,也可以找到元素向左遍历第一个比他大的元素。

(也就是说在元素进栈前他向左拓展的区间已经确定,在出栈前她能向右拓展的区间也能确定)

代码如下:

#include<map>     
#include<stack>            
#include<queue>            
#include<vector>    
#include<string>  
#include<math.h>            
#include<stdio.h>            
#include<iostream>            
#include<string.h>            
#include<stdlib.h>    
#include<algorithm>   
#include<functional>    
using namespace std;
typedef long long  ll;
#define inf  1000000000       
#define mod 1000000007             
#define maxn  286000  
#define PI 3.1415926
#define lowbit(x) (x&-x)            
#define eps 1e-9  
struct node
{
	long long x, y, l, r;
}str[maxn];
stack<node>t;
int  main()
{
	long long  T, i, j, n, m, k, sum;
	scanf("%lld", &T);
	while (T--)
	{
		sum = 0;
		scanf("%lld", &n);
		for (i = 1;i <= n;i++)
		{
			scanf("%lld", &str[i].x);
			str[i].y = i;
		}
		for (i = 1;i <= n;i++)
		{
			str[i].l = i;
			while (t.empty() == 0 && t.top().x>str[i].x)
			{
				str[t.top().y].r = i - 1;
				str[i].l = str[t.top().y].l;
				t.pop();
			}
			t.push(str[i]);
		}
		while (t.empty() == 0)
		{
			str[t.top().y].r = n;
			t.pop();
		}
		for (i = 1;i <= n;i++)
			sum += str[i].x*(i - str[i].l + 1)*(str[i].r - i + 1);
		printf("%lld\n", sum);
	}
}




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值