P2866 [USACO06NOV]糟糕的一天Bad Hair Day
题意翻译
农夫约翰有N (N \leq 80000)N(N≤80000)头奶牛正在过乱头发节。每一头牛都站在同一排面朝东方,而且每一头牛的身高为h_ihi。第NN头牛在最前面,而第11头牛在最后面。 对于第ii头牛前面的第jj头牛,如果h_i>h_{i+1}hi>hi+1并且h_i>h_{i+2}hi>hi+2 \cdots⋯ h_i>h_jhi>hj,那么认为第ii头牛可以看到第i+1i+1到第jj头牛
定义C_iCi为第ii头牛所能看到的别的牛的头发的数量。请帮助农夫约翰求出\sum_{i=1}^n C_i∑i=1nCi
题目描述
Some of Farmer John's N cows (1 ≤ N ≤ 80,000) are having a bad hair day! Since each cow is self-conscious about her messy hairstyle, FJ wants to count the number of other cows that can see the top of other cows' heads.
Each cow i has a specified height hi (1 ≤ hi ≤ 1,000,000,000) and is standing in a line of cows all facing east (to the right in our diagrams). Therefore, cow i can see the tops of the heads of cows in front of her (namely cows i+1, i+2, and so on), for as long as these cows are strictly shorter than cow i.
Consider this example:
=
= =
= - = Cows facing right -->
= = =
= - = = =
= = = = = =
1 2 3 4 5 6 Cow#1 can see the hairstyle of cows #2, 3, 4
Cow#2 can see no cow's hairstyle
Cow#3 can see the hairstyle of cow #4
Cow#4 can see no cow's hairstyle
Cow#5 can see the hairstyle of cow 6
Cow#6 can see no cows at all!
Let ci denote the number of cows whose hairstyle is visible from cow i; please compute the sum of c1 through cN.For this example, the desired is answer 3 + 0 + 1 + 0 + 1 + 0 = 5.
输入输出格式
输入格式:
Line 1: The number of cows, N.
Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i.
输出格式:
Line 1: A single integer that is the sum of c1 through cN.
输入输出样例
6
10
3
7
4
12
2
5
单调栈经典题,首先我们维护一个严格递减的单调栈,当我们读入一个新元素时,如果这个新元素小于栈顶元素,就入栈,否则就弹出栈顶元素,并且ans加上两个元素下标之差-1(可以画图看看),同时我们还应该在最后赋一个极大值来将栈中所有的元素弹出,这样问题就解决了,记得开long long。
#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#define maxn 80005
using namespace std;
stack<int>s; inline int read()
{
char c=getchar();
int res=,x=;
while(c<''||c>'')
{
if(c=='-')
x=-;
c=getchar();
}
while(c>=''&&c<='')
{
res=res*+(c-'');
c=getchar();
}
return x*res;
} long long ans;
int n,aa;
long long a[maxn]; int main()
{
n=read();
for(int i=;i<=n;i++)
{
aa=read();
a[i]=aa;
}
a[n+]=;//赋成极大值
for(int i=;i<=n+;i++)
{
if(s.empty()||a[i]<a[s.top()])//维护一个单调递减栈
{
s.push(i);
}
else
{
while(!s.empty()&&a[i]>=a[s.top()])
{
ans+=(long long)(i-s.top()-);//加上两个元素的下标之差-1
s.pop();
}
s.push(i);
}
}
printf("%lld",ans);
return ;
}
To the world you may be one person, but to one person you may be the world.
对于世界而言,你是一个人;但是对于某个人,你是他的整个世界。
--snowy 2019-01-18 14:06:50