到现在为止线段树我仍然没有系统的复习一遍,今日份的暑假练习从 CF 开始,不过今天对树状数组和单调栈有了更深刻的了解,昨天晚上,树状数组反向建树的操作现在想起来还是有些玄幻,不过要求区间的最大值,其实线段树更能够解决此类问题,树状数组只是求 [1,x] 区间内的值,当然在题目要求每次求所有元素内的最值的时候,树状数组还是很好用的,今天遇到了一个这样的问题,还傻啦吧唧的用贪心做。
现在差不多知道了什么时候利用单调栈了,果然看的题解多了总会找到规律
利用单调栈对于 a[i] 相当于从 i 位置向左或向右遍历,找出第一个大于或等于 a[i] 的位置,然后利用区间和将去掉的部分表示进来
以栈顶最大为例:
stack<int> s;
for(i=1;i<=n;i++)
{
while(s.size() && a[s.top]>a[i]) s.pop();
if(s.empty()) pos[i]=0;
else{
pos[i]=s.top();
}
s.push(i);
}
如果操作过后,栈为空,那么说明,栈内所有元素都比 a[i] 大,所以目前 a[i] 最小
若不为空,那么记录 i 位置记录左边第一个小于 a[i] 的位置即可