info: { blogIcon: 'https://cdn.luogu.com.cn/upload/usericon/765493.png', blogUser: 'OIerBoy', blogAvatar: 'https://cdn.luogu.com.cn/upload/usericon/765493.png', blogStartDate: '2023-04-22', webpageTitleOnblur: '(o?v?)ノ Hi', webpageTitleOnblurTimeOut: 1000, webpageTitleFocus: '(*′?`*) 欢迎回来!', webpageTitleFocusTimeOut: 1000, webpageIcon: "https://cdn.jsdelivr.net/gh/BNDong/Cnblogs-Theme-SimpleMemory@master/img/webp/blog_logo.webp", { enable: true, // 是否开启日/夜间模式切换按钮 auto: { // 自动切换相关配置 enable: false, // 开启自动切换 dayHour: 5, // 日间模式开始时间,整数型,24小时制 nightHour: 19 // 夜间模式开始时间,整数型,24小时制 } } },

[ABC305D] Sleep Log题解

题目大意

N 个时刻:

  • i 为奇数时,Ai 表示刚刚起床的时刻。
  • i 为偶数时,Ai 表示开始睡觉的时刻。

Q 次询问,每次求在 [l,r] 区间内睡了多长时间。

分析

首先我们要考虑处理边界情况。

每一次二分查找第一个大于等于 lr 的时刻 xy

分别判断 xy 是起床还是开始睡觉。

  • 如果是起床,则说明上一段时间正在睡觉,就记录贡献。
  • 如果是开始睡觉,则说明上一段时间未睡觉,就不用管。

处理完边界条件后就只需要处理中间整段的睡觉时间。

这个用一个前缀和维护即可。

具体细节请看代码。

Code

#include<bits/stdc++.h>
#define int long long
#define N 200005
using namespace std;
int n,Q,a[N];
int p[N];
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		p[i]+=p[i-1];//前缀和
		if(i%2==1)p[i]+=a[i]-a[i-1];
	}
	cin>>Q;
	while(Q--){
		int l,r,ans=0;
		cin>>l>>r;
		int x=lower_bound(a,a+n,l)-a;//lower_bound查找下一个时刻
		int y=lower_bound(a,a+n,r)-a;
		if(x%2==1)ans+=a[x]-l;//判断边界贡献
		if(y%2==1)ans+=r-a[y-1];
		ans+=p[y-1]-p[x];//处理中间部分
		cout<<ans<<endl;
	}
	return 0;
}

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