AT_abc305_d的题解

(一)

直接用二分找出大于输入的 \(l\)\(r\) 的数。

利用前缀和快速求出中间的几块的睡眠时间和。

然后处理最左边和最右边两块的睡眠时间。

二分可以用 upper_bound 直接解决。

(二)

AC 代码。

#include<bits/stdc++.h>
using namespace std;
int n,q,a[200001],s[200001],l,r;
int solve(int x,int y){
	if(x&1)return s[y/2-1]-s[x/2];
	else return s[y/2-1]-s[x/2-1];
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n/2;i++)s[i]=s[i-1]+a[i*2+1]-a[i*2];
	cin>>q;
	while(q--){
		cin>>l>>r;
		int sitl=upper_bound(a+1,a+n+1,l)-a;
		int sitr=upper_bound(a+1,a+n+1,r)-a;
		int ans=solve(sitl,sitr);
		if(sitl&1){
			if(sitr&1)cout<<a[sitl]-l+r-a[sitr-1]+ans<<endl;
			else cout<<a[sitl]-l+ans<<endl;
		}
		else{
			if(sitr&1)cout<<r-a[sitr-1]+ans<<endl;
			else cout<<ans<<endl;
		}
	}
	return 0;
}
posted @ 2024-03-28 08:19  Jerry_heng  阅读(15)  评论(0)    收藏  举报