标签:
链接:http://vjudge.net/problem/UVA-1619
分析:首先计算前缀和,后面会用到。设每个i都属于一个满足下述条件的最大区间(因为题意说是正整数序列,区间当然越大越好),a[i]为区间中的最小值,然后预处理出以i为轴向左和向右延伸的最远位置L[i]和R[i]来标记这个区间,最后就是O(n)的枚举。
1 #include <cstdio> 2 3 const int maxn = 1e5+5; 4 5 int n, a[maxn], L[maxn], R[maxn]; 6 long long prefix_sum[maxn]; 7 8 int main() { 9 int T = 0; 10 while (scanf("%d", &n) == 1) { 11 if (T++) printf("\n"); 12 a[0] = -1; a[n+1] = -1; prefix_sum[0] = 0; 13 for (int i = 1; i <= n; i++) { 14 scanf("%d", &a[i]); 15 prefix_sum[i] = prefix_sum[i-1] + a[i]; 16 L[i] = i; R[i] = i; 17 } 18 for (int i = 1; i <= n; i++) 19 while (a[i] <= a[L[i]-1]) L[i] = L[L[i]-1]; 20 for (int i = n; i >= 1; i--) 21 while (a[i] <= a[R[i]+1]) R[i] = R[R[i]+1]; 22 long long ans = a[1] * a[1]; 23 int l = 1, r = 1; 24 for (int i = 1; i <= n; i++) { 25 long long v = (prefix_sum[R[i]] - prefix_sum[L[i]-1]) * a[i]; 26 if (v > ans || (v == ans && r-l > R[i]-L[i])) { 27 ans = v; 28 l = L[i], r = R[i]; 29 } 30 } 31 printf("%lld\n", ans); 32 printf("%d %d\n", l, r); 33 } 34 return 0; 35 }
标签:
原文地址:http://www.cnblogs.com/XieWeida/p/5899890.html