Hihocoder1620
这个题是个模版题,读完以后稍微思考就能用单调队列来做,首先我们看完之后我会发现我们肯定是要顺着来做的?
(1):那么有一种方法是 我们枚举每个点,然后用线段树维护一下第一个大于等于它的值?????? (nlog(n)) 也不是很难写,但是这样就很秀了,神仙操作。。。。。。。。。。。。
这个是读完题后最直观的思维分析
(2):接下来还有就是性质分析,我们维护一个单调递增的序列就可。然后对每个数让他们出队,入队,这不就变成了一个很简单的单调队列了吗???????
但是第一种思维也很直接了当啊,很容易就进了第一个的陷阱,然后出不来了。。。。。。。。。这个要怎么办还真是个问题
要顺入第二种思维的话我们就得想,如果一个值找到了一个比他大的值,那么这个值也就没用了,这样的话就很容易拐入单调队列的思维里面了。
下面是代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #include <bitset> 6 #include <iostream> 7 typedef long long ll; 8 using namespace std; 9 const int maxn=(int)(1e5+100); 10 int n; 11 int day[maxn]; 12 int ai[maxn]; 13 int que[maxn]; 14 int head=0,tail=0; 15 int main(){ 16 scanf("%d",&n); 17 for(int i=1;i<=n;i++) scanf("%d",&ai[i]); 18 memset(day,-1,sizeof(day)); 19 for(int i=1;i<=n;i++){ 20 while(head<tail&&ai[que[tail]]<ai[i]){ 21 day[que[tail]]=i-que[tail]; 22 --tail; 23 } 24 que[++tail]=i; 25 } 26 for(int i=1;i<=n;i++) printf("%d\n",day[i]); 27 return 0; 28 }