AT_abc305_d的題解

Jerry_heng發表於2024-03-28

(一)

直接用二分找出大於輸入的 \(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;
}