P2866 [USACO06NOV]糟糕的一天Bad Hair Day--单调栈

P2866 [USACO06NOV]糟糕的一天Bad Hair Day

题意翻译

农夫约翰有N (N \leq 80000)N(N80000)头奶牛正在过乱头发节。每一头牛都站在同一排面朝东方,而且每一头牛的身高为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_ii=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.

 

输入输出样例

输入样例#1: 复制
6
10
3
7
4
12
2
输出样例#1: 复制
5
单调栈经典题,首先我们维护一个严格递减的单调栈,当我们读入一个新元素时,如果这个新元素小于栈顶元素,就入栈,否则就弹出栈顶元素,并且ans加上两个元素下标之差-1(可以画图看看),同时我们还应该在最后赋一个极大值来将栈中所有的元素弹出,这样问题就解决了,记得开long long。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<queue>
 7 #include<stack>
 8 #include<algorithm>
 9 #define maxn 80005
10 using namespace std;
11 stack<int>s;
12 
13 inline int read()
14 {
15     char c=getchar();
16     int res=0,x=1;
17     while(c<'0'||c>'9')
18     {
19         if(c=='-')
20         x=-1;
21         c=getchar();
22     }
23     while(c>='0'&&c<='9')
24     {
25         res=res*10+(c-'0');
26         c=getchar();
27     }
28     return x*res;
29 }
30 
31 long long ans;
32 int n,aa;
33 long long a[maxn];
34 
35 int main()
36 {
37     n=read();
38     for(int i=1;i<=n;i++)
39     {
40         aa=read();
41         a[i]=aa;
42     }
43     a[n+1]=10000000005;//赋成极大值 
44     for(int i=1;i<=n+1;i++)
45     {
46         if(s.empty()||a[i]<a[s.top()])//维护一个单调递减栈 
47         {
48             s.push(i);
49         }
50         else 
51         {
52             while(!s.empty()&&a[i]>=a[s.top()])
53             {
54                 ans+=(long long)(i-s.top()-1);//加上两个元素的下标之差-1 
55                 s.pop();
56             }
57             s.push(i);
58         }
59     }
60     printf("%lld",ans);
61     return 0;
62 }
View Code

 

To the world you may be one person, but to one person you may be the world.
对于世界而言,你是一个人;但是对于某个人,你是他的整个世界。

                                                                                                                                                                --snowy                                                                                                                                                                                         2019-01-18   14:06:50


posted @ 2019-01-18 14:07  snowy2002  阅读(437)  评论(0编辑  收藏  举报