King of Range
链接: link.
题目:
题意:
对
n
n
n个数进行
m
m
m次查询,求区间内最大值
−
-
−最小值
>
k
>k
>k的区间数.
题解:
该问题相当于求最大值
−
-
−最小值
<
=
k
<=k
<=k的区间数,而后用总数减去该数.调用两个队列,一个用于维护最大值,一个用于维护最小值。每次查询时都要将
r
r
r推入两个队列中,若当前满足最大值
−
-
−最小值
<
=
k
<=k
<=k,则直接用
a
n
s
ans
ans减去此时区间数,否则则
l
+
+
l++
l++使不满足的情况出队直至满足最大值
−
-
−最小值
<
=
k
<=k
<=k,再用
a
n
s
ans
ans减去此时区间数。
#include<bits/stdc++.h>
using namespace std;
deque<int>ma,mb;
int a[100010];
void push(int x)
{
while(!ma.empty()&&a[ma.back()]<=a[x])ma.pop_back();
ma.push_back(x);
while(!mb.empty()&&a[mb.back()]>=a[x])mb.pop_back();
mb.push_back(x);
}
void pop(int x)
{
if(ma.front()==x)ma.pop_front();
if(mb.front()==x)mb.pop_front();
}
int main()
{
int n,m,k;
long long ans;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++)
{
cin>>k;
ma.clear();
mb.clear();
ans=1ll*n*(n+1)/2;
for(int l=1,r=1;r<=n;r++)
{
push(r);
int mx=ma.front(),mn=mb.front();
if(a[mx]-a[mn]<=k)ans -=r-l+1;
else
{
while(a[ma.front()]-a[mb.front()]>k)pop(l++);
ans-=r-l+1;
}
}
cout<<ans<<endl;
}
}