(题目名称好评
题意:维护一个单调栈,询问区间 元素依次入栈的过程中栈的大小为1的个数。
换句话说,就是区间 有多少个元素 满足 是 中最"大"的。
(题目中, 比 大,是指 )
因此,我们可以通过单调栈求出每个元素前面第一个比它“大”的元素所在的位置,令 。
在询问时求出 中有多少个元素 满足 即可。
现在问题来了,如何快速求 中有多少个元素 满足 ?
考虑离线,令 为 的桶数组
从位置 开始统计
在位置 时,将 中已经被统计的减去,这些不在询问区间内,不应该被计算。
在位置 时 ,加上 ,即 中 的个数。
数组使用树状数组维护。
for(int i=1;i<=n;i++){
while(!S.empty()&&!(a[S.top()]!=a[i]&&b[i]<b[S.top()])) S.pop();
if(!S.empty()){
last[i]=S.top()+1;
}else{
last[i]=1;
}
S.push(i);
}
for(int i=1;i<=q;i++){
L[l[i]].push_back(i);
R[r[i]].push_back(i);
}
for(int ll=1;ll<=n;ll++){
for(int i:L[ll]){
ans[i]-=sum(ll);
}
add(last[ll],1);
for(int i:R[ll]){
ans[i]+=sum(l[i]);
}
}