CF1817A的题解
(一)
先找出符合 \(a_i \ge a_{i+1} \ge a_{i+2}\) 的所有 \(i\)。
将问题按左端点(或右端点)排序。
对于每一个问题,找出最左的符合条件的 \(l\) 和最右的符合条件的 \(r\)。
由于时间会超,\(r\) 用二分搜。
然后一般的 \(ans\) 就是给定区间长度减去 \(r\) 和 \(l\) 间距离。
特殊情况见代码。
(二)
AC 代码。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q,l,a[200011],k,ans[200011],be[200011];
struct node{
int x,y;
}dis[200011];
struct nodd{
int x,y,sit;
}ask[200011];
bool cmp(nodd p1,nodd p2){
return p1.x<p2.x||p1.x==p2.x&&p1.y<p2.y;
}
signed main(){
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
for(int i=1;i<=n-2;i++)if(a[i]>=a[i+1]&&a[i+1]>=a[i+2])be[++k]=i;
be[k+1]=1000000;
for(int i=1;i<=q;i++){
scanf("%lld%lld",&ask[i].x,&ask[i].y);
ask[i].sit=i;
}
sort(ask+1,ask+q+1,cmp);
for(int i=1;i<=q;i++){
while(be[l]<ask[i].x&&l<k)l++;
int ll=l,rr=k,r;
while(ll<=rr){
int mid=(ll+rr)>>1;
if(be[mid]+2<=ask[i].y)r=mid,ll=mid+1;
else rr=mid-1;
}
if(be[l]+2>ask[i].y||be[l]<ask[i].x)ans[ask[i].sit]=ask[i].y-ask[i].x+1;
else ans[ask[i].sit]=ask[i].y-ask[i].x+1-(r-l+1);
}
for(int i=1;i<=q;i++)printf("%lld\n",ans[i]);
return 0;
}

浙公网安备 33010602011771号