洛谷 2866 [USACO06NOV]糟糕的一天Bad Hair Day

【题意概述】

  给出一个长度为n的序列a,求有多少对[i,j]满足i<j且a[i]>max(a[i+1],a[i+2],...,a[j]).

【题解】

  单调栈。

  倒着处理序列的元素,维护一个单调递减的栈,同时记录栈中的每个元素进栈的时间。如果当前元素x大于栈顶元素,那么栈顶到第二个元素在原素列之间的这一段就都是可以被x看见的,答案加上time[top]-time[top-1].

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long
 5 #define rg register
 6 #define N 200010
 7 using namespace std;
 8 LL n,top,cnt,a[N],s[N],time[N];
 9 LL ans;
10 inline LL read(){
11     LL k=0,f=1; char c=getchar();
12     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
13     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
14     return k*f;
15 }
16 int main(){
17     n=read();
18     for(rg int i=1;i<=n;i++) a[i]=read();
19     for(rg int i=1;i<=n;i++){
20         LL x=a[n-i+1];
21         while(s[top]<x&&top) ans+=time[top]-time[top-1],time[top--]=0;
22         if(s[top]!=x) s[++top]=x; 
23         time[top]=i;
24 //        printf("[%d %d]
",top,ans);
25 //        for(rg int j=1;j<=top;j++) printf("%d ",time[j]); puts("");
26     }
27     printf("%lld
",ans);
28     return 0;
29 }
View Code
原文地址:https://www.cnblogs.com/DriverLao/p/9397339.html