Minimum Sum(单调栈) AtCoder Grand Contest 005
Posted zjj0624
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Minimum Sum(单调栈) AtCoder Grand Contest 005相关的知识,希望对你有一定的参考价值。
题意
给你一个由1~n的序列,
a
1
,
a
2
,
a
3
.
.
.
.
.
a
n
a_1,a_2,a_3.....a_n
a1,a2,a3.....an,每个数字都只出现一次,没有重复,让你求由这个序列所有子序列的最小值的和.
思路
我们求出每一个点影响的最大的左右区间,然后用一点点组合数的知识来写.
求出每个点的左右区间用单调栈来实现.
注意要开LL.
代码
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N=2e5+10;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
ll a[N],le[N],ri[N];
int main()
int n;
cin>>n;
for(int i=1 ; i<=n ; i++) cin>>a[i];
stack<int>s;
for(int i=1 ; i<=n ; i++)
while(!s.empty()&&a[s.top()]>a[i])
ri[s.top()]=i;
s.pop();
s.push(i);
while(!s.empty())
ri[s.top()]=n+1;
s.pop();
for(int i=n ; i>=1 ; i--)
while(!s.empty()&&a[s.top()]>a[i])
le[s.top()]=i;
s.pop();
s.push(i);
while(!s.empty())
le[s.top()]=0;
s.pop();
ll ans=0;
for(int i=1 ; i<=n ; i++)
//cout<<i<<" "<<le[i]<<" "<<ri[i]<<endl;
ans+=a[i]*(ri[i]-le[i]-1+(ri[i]-i-1)*(i-le[i]-1));
cout<<ans<<endl;
return 0;
以上是关于Minimum Sum(单调栈) AtCoder Grand Contest 005的主要内容,如果未能解决你的问题,请参考以下文章
[Agc005D/At2060] Minimum Sum - 单调栈