G - Bad Hair Day
题目描述
Farmer John的奶牛在风中凌乱了它们的发型……
每只奶牛都有一个身高hi(1 ≤ hi ≤ 1,000,000,000),现在在这里有一排全部面向右方的奶牛,一共有N只(1 ≤ N ≤ 80,000)。对于奶牛i来说,如果奶牛i+1,i+2,……,N这些奶牛的身高严格小于奶牛i,则奶牛i可以看到它们凌乱的发型。
比如下面这个例子:* * * * = *
= * * * = *
= * - * = * 奶牛面向这边-->
= * = * = *
= - = = = *
= = = = = =
1 2 3 4 5 6
('*'表示空的,这是译者为了格式特意弄的,原题没有)
令ci表示第i只奶牛能够看到的发型数量,请计算c1 + c2 + c3 + … + cN的值
对于上面这个例子,答案为3 + 0 + 1 + 0 + 1 + 0=5。输入
第一行:奶牛数量N
第二到N+1行:第i+1行输入奶牛i的身高输出
第一行:一个整数即c1到cN的和
样例输入
6
10
3
7
4
12
2样例输出
5
首先我们先模拟一下:
身高: 10 3 7 4 12 2
牛(下标): 1 2 3 4 5 6
就以牛1为例子进行模拟:
- 首先,第一头牛要看他前面的牛,那就让牛1 入栈
- 牛1要先和牛2比身高,如果牛2比他低, 则牛1可看到牛2,牛1仍然在栈顶,然后sum(牛1) += 1;
- 牛1再看牛3, 发现又能看到 ,再加1;
- 牛1继续看,能看到牛4, 再加1;
- 牛1再看牛5时,发现看不到,则牛1出栈,牛5入栈,改牛5看他前面的牛
- .......................................
从此过程不难看出,该题和单调栈息息相关,一直在维护栈顶元素
ac代码:
/*该题利用了单调栈的性质,一直维护栈顶元素
,栈顶元素每次看到的数字之和即为栈顶元素可以看到的所有数目*/
#include<cstdio>
#include<iostream>
#include<stack>
using namespace std;
const int maxn = 8*1e4+5;
long long a[maxn];
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%lld", &a[i]);
stack<long long>S;
S.push(a[0]);
long long sum = 0;
for(int i = 1; i < n; i++){
while(S.size() > 0&&S.top() <= a[i]) S.pop();
sum += S.size();
S.push(a[i]);
}
printf("%lld\n", sum);
return 0;
}