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;
}

浙公网安备 33010602011771号