题目连接:
http://acm.hdu.edu.cn/showproblem.php?pid=1506
题目大意:
给出一个数列An,问以Ai为最小值的区间内有多少个元素?
解题思路:
手动模拟一个栈。栈内元素为一个单调不递减序列。当新元素Ai需要进栈,如果栈顶元素大于Ai,弹出栈顶元素,直到栈顶元素不大于Ai,Ai进栈。
这里可以保证i是高为栈顶元素的矩形向后延伸的边界,弹出过程中记录高为Ai的矩阵向前延伸的边界。
1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 using namespace std; 6 const int maxn = 100005; 7 #define LL long long//要用LL,数据范围太大,int会溢出 8 struct node 9 { 10 LL x, index; 11 } Stack[maxn]; 12 13 int main () 14 { 15 LL n; 16 while (scanf ("%I64d", &n), n) 17 { 18 LL sum = 0; 19 LL head, last, num, m; 20 head = 0; 21 last = -1; 22 for (LL i=0; i<=n; i++) 23 { 24 if (i == n)//在数列后面加一个0,以便于清空栈内元素 25 num = 0; 26 else 27 scanf ("%I64d", &num); 28 m = i;//记录当前元素向前延伸的边界 29 while (head<=last && Stack[last].x>num) 30 { 31 sum = max(sum, (i - Stack[last].index)*Stack[last].x); 32 m = Stack[last].index; 33 last --; 34 } 35 Stack[++last].index = m; 36 Stack[last].x = num; 37 } 38 printf ("%I64d ", sum); 39 } 40 return 0; 41 }