链接:https://ac.nowcoder.com/acm/contest/223/C
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给出长度为n的序列a,其中第i个元素为,定义区间(l,r)的价值为
请你计算出
输入描述:
第一行输入数据组数T 对于每组数据,第一行为一个整数n,表示序列长度 接下来一行有n个数,表示序列内的元素
输出描述:
对于每组数据,输出一个整数表示答案
示例1
输入
复制
3 3 4 2 3 5 1 8 4 3 9 20 2 8 15 1 10 5 19 19 3 5 6 6 2 8 2 12 16 3 8 17
输出
复制
5 57 2712
说明
对于一组测试数据的解释: 区间[1, 2]的贡献为:4 - 2 = 2 区间[1, 3]的贡献为:4 - 2 = 2 区间[2, 3]的贡献为:3 - 2 = 1 2 + 1 + 2 = 5.
备注:
不保证数据随机生成!
单调栈解决;
分两种情况讨论,1,以当前点为端点;2,不以当前点为端点
#include <bits/stdc++.h>
#define maxn 100005
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
ll a[maxn];
stack< pair<ll,ll> > q;
typedef pair<ll,ll> p;
int main()
{
ll t,n;
cin >> t;
while(t--)
{
while(!q.empty())q.pop();
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
}
a[0] = inf + 1; a[n+1] = inf;
ll sum = 0;
q.push(make_pair(0,a[0]));
q.push(make_pair(1,a[1]));
for(int i = 2; i <= n + 1; i ++)
{
p x;
x = q.top();
while(x.second <= a[i])
{
q.pop();
sum += (i - x.first - 1) * x.second;
sum += (i - x.first) * (x.first - q.top().first - 1) * x.second;
x = q.top();
}
q.push(make_pair(i,a[i]));
}
while(!q.empty())q.pop();
a[0] = -inf - 1; a[n+1] = -inf;
q.push(make_pair(0,a[0]));
q.push(make_pair(1,a[1]));
for(int i = 2; i <= n + 1; i ++)
{
p x;
x = q.top();
while(x.second >= a[i])
{
q.pop();
sum -= (i - x.first - 1) * x.second;
sum -= (i - x.first) * (x.first - q.top().first - 1) * x.second;
x = q.top();
}
q.push(make_pair(i,a[i]));
}
cout << sum << endl;
}
return 0;
}