您的位置:首页 > 其它

2014湘潭邀请赛 C题 湘大OJ 1205 Range (单调栈)

2014-09-03 22:36 155 查看

Problem Description

For an array, the range function is defined below: Range(A)=Max(A)-Min(A)+1; For example, suppose A={1,2,3,4,5}, then Range(A)=5-1+1=5. Now, given an array A(length≤100000), you are going to calcalute the sum of all subarray's range. i.e sigma(i,j){Range(A[i,j])}.

Input

First line contain an integer T, there are T(1≤T≤100) cases. For each case T. The length N(1≤N≤100000), and N integers A[i](1≤A[i]≤109).

Output

Output case number first, then the answer.

Sample Input

1
5
1 2 3 4 5

Sample Output

Case 1: 35


实际上就是求出以第i个数为最大值得区间个数 和 以第i个数为最小值得区间个数 ,可以利用单调栈的思想,和poj2559几乎是一个题。都是求出以第i个为最值,往左往右能扩展出的范围。

#include <iostream>
#include <cstdio>
using namespace std;
typedef __int64 LL;
const int maxn = 100000+10;
int t, n;
LL l[maxn], r[maxn], a[maxn];
LL solve()
{
LL ans = (LL)(n+1)*n/2;
l[1] = 1;
for(int i = 2; i <= n; i++) {
int tmp = i;
while(tmp > 1 && a[tmp-1] >= a[i]) tmp = l[tmp-1];
l[i] = tmp;
}
r
= n;
for(int i = n-1; i > 0; i--) {
int tmp = i;
while(tmp < n && a[tmp+1] > a[i]) tmp = r[tmp+1];
r[i] = tmp;
}
for(int i = 1; i <= n; i++) ans -= a[i] * (LL)(i - l[i] + 1) * (LL)(r[i] - i + 1);
l[1] = 1;
for(int i = 2; i <= n; i++) {
int tmp = i;
while(tmp > 1 && a[tmp-1] <= a[i]) tmp = l[tmp-1];
l[i] = tmp;
}
r
= n;
for(int i = n-1; i > 0; i--) {
int tmp = i;
while(tmp < n && a[tmp+1] < a[i]) tmp = r[tmp+1];
r[i] = tmp;
}
for(int i = 1; i <= n; i++) ans += a[i] * (LL)(i - l[i] + 1) * (LL)(r[i] - i + 1);

return ans;
}
int main()
{
cin >> t;
for(int ca = 1; ca <= t; ca++) {
cin >> n;
for(int i = 1; i < n+1; i++) scanf("%I64d", &a[i]);
printf("Case %d: %I64d\n", ca, solve());
}
return 0;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: