poj 3250 bad hair day
Posted jack_yyc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 3250 bad hair day相关的知识,希望对你有一定的参考价值。
题目大意:
一个数列,求对于每个ai右边有几个比它小的数,且这些比他小的数到ai之间没有比ai大的数。
思路:
问题可以很容易地转换为求右边第一个大于等于它的数的位置
然后就可以想到单调栈
有两种做法:
一:
从后向前走,栈内为单调递减,栈内元素需要记录一下它的值和位置,然后每个元素进来的时候弹出直到栈顶比该元素小,答案加上栈顶到现在位置的距离即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<set> 10 #define inf 2147483611 11 #define ll long long 12 #define MAXN 80101 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1; 17 char ch;ch=getchar(); 18 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 19 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 20 return x*f; 21 } 22 struct data 23 { 24 int pos,val; 25 }st[MAXN]; 26 int n,a[MAXN],top; 27 ll ans; 28 int main() 29 { 30 n=read(); 31 for(int i=1;i<=n;i++) a[i]=read(); 32 st[++top].val=inf,st[top].pos=n+1; 33 for(int i=n;i>=1;i--) 34 { 35 while(st[top].val<a[i]&&top) top--; 36 st[++top].pos=i,st[top].val=a[i]; 37 ans+=st[top-1].pos-i-1; 38 } 39 printf("%lld",ans); 40 }
二:
首先可以知道答案可以转化为每个点左边有几个比它大的数且之间没有更大的数则:
从前向后走,栈内为单调递减,栈内元素只需要记录一下它的值,然后对于每个点,我们弹出同上,答案只需要加上当前站内元素数,然后再把元素加入栈。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<set> 10 #define inf 2147483611 11 #define ll long long 12 #define MAXN 80101 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1; 17 char ch;ch=getchar(); 18 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 19 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 20 return x*f; 21 } 22 int n,h,st[MAXN],top; 23 ll ans; 24 int main() 25 { 26 n=read(); 27 for(int i=1;i<=n;i++) 28 { 29 h=read(); 30 while(top&&st[top-1]<=h) top--; 31 ans+=top; 32 st[top++]=h; 33 } 34 printf("%lld",ans); 35 }
以上是关于poj 3250 bad hair day的主要内容,如果未能解决你的问题,请参考以下文章