CF1817A的题解

(一)

先找出符合 aiai+1ai+2 的所有 i

将问题按左端点(或右端点)排序。

对于每一个问题,找出最左的符合条件的 l 和最右的符合条件的 r

由于时间会超,r 用二分搜。

然后一般的 ans 就是给定区间长度减去 rl 间距离。

特殊情况见代码。

(二)

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;
}
posted @   Jerry_heng  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示