首页 > 其他分享 >ABC 305D Sleep Log

ABC 305D Sleep Log

时间:2024-05-27 21:33:30浏览次数:22  
标签:睡眠 ABC int 305D Sleep flag2 flag1 maxn ds

题意

  • 现在给你一个高桥君的睡眠表a,若i为奇数,那么高桥君在a[i]~a[i+1]这段时间没有睡觉,反之则处于睡眠期间。现在有q次询问,每次询问会给出l,r,分别表示起始时间和终止时间,求这段时间内高桥君的睡眠时间

思路

  • 我们可以将每个[l,r]拆成若干个整块的睡眠时间或未睡眠时期加上零碎的睡眠时间或未睡眠时间。类似于分块的想法,整块我们统一前缀和处理,而碎块单独处理即可。
  • 这里我们遇到的问题是:
  1. 如何表示一个区间,并判断是否为睡眠时间。
  2. 需要对所有的睡眠时间单独拎出来进行前缀和,否则会tle。
  • 对于第一个问题我们可以采取用map储存一个数对对于一个数的映射,数对存储一个区间的左端点和右端点,而那一个数就是我们对块的标记的序号,若为奇数,则为未睡眠时期,反之为睡眠时期。
  • 对于第二个问题,我们单独开一个数组即可,然后我们可以很明显的发现,在原数组睡眠时间段的序号对应的单独拎出来的数组里的序号是两倍关系,这样我们就能很快的使用前缀和了。
  • 想补充的一点是,注意一下端点的情况,具体可以看码。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
map<pair<int,int>,int>ds;
map<int,pair<int,int>>ddd;
const int maxn=2e5+10;
int a[maxn],slp[maxn],sum[maxn],cnt; 

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	
	int n;
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=0;i<n-1;i++)
	{
		ds[make_pair(a[i],a[i+1])]=i+1;
		ddd[i+1]=make_pair(a[i],a[i+1]);
	}
	int flag=1;
	for(int i=0;i<n-1;i++) 
	{
		if(flag%2==0) slp[++cnt]=a[i+1]-a[i];
		flag++;
	}
	for(int i=1;i<=cnt;i++) sum[i]=sum[i-1]+slp[i];
	int q;
	cin>>q;
	while(q--)
	{
		int ans=0;
		int l,r;
		cin>>l>>r;
		int flag1=lower_bound(a,a+n,l)-a;
		int d1=ds[make_pair(a[flag1-1],a[flag1])];
		int flag2=lower_bound(a,a+n,r)-a;
		int d2=ds[make_pair(a[flag2-1],a[flag2])];
		//for(int i=d1+1;i<=d2-1;i++) if(i%2==0) ans+=ddd[i].second-ddd[i].first;
        int begin=d1+1;
		int end=d2-1;
		if(begin%2==1) begin++;
		if(end%2==1) end--;
		ans+=sum[end/2]-sum[begin/2-1];	
		if(d1%2==0) ans+=a[flag1]-l;
		if(d2%2==0) ans+=r-a[flag2-1];
		cout<<ans<<endl;
	}
	
	
	
	return 0;
}

标签:睡眠,ABC,int,305D,Sleep,flag2,flag1,maxn,ds
From: https://www.cnblogs.com/lulu7/p/18216573

相关文章

  • ABC 355 D题Intersecting Intervals
    题意现在有n条线段,每条线段的左端点和右端点依次给出,求有多少对线段有交集。思路考虑正难则反的想法,我们考虑着n条线段全部两两相交的时候,那么答案就是(n-1)*n/2,现在我们要求出有多少对线段是不相交的。当两条线段不相交的时候,显然有其中一条线段的左端点严格大于另一条线......
  • AtCoder abc325D
    原题链接ProblemStatementThereare\(N\)productslabeled\(1\)to\(N\)flowingonaconveyorbelt.AKeyenceprinterisattachedtotheconveyorbelt,andproduct\(i\)enterstherangeoftheprinter\(T_i\)microsecondsfromnowandleavesit......
  • ABC341
    D-Onlyoneoftwohttps://atcoder.jp/contests/abc341/tasks/abc341_d数论,二分求第K大设\(L\)是\(N\)和\(M\)的最小公倍数。那么,有\(\lfloor\frac{X}{L}\rfloor\)个不大于\(X\)的正整数能被\(\lfloor\frac{X}{L}\rfloor\)整除,因此有\(\lfloor\frac{X}{N......
  • ABC355 D区间相交问题
    ABC355D区间相交问题题意给出n个区间,每个区间给出左端点(l)和右端点(r),判断有多少区间成对相交。分析如果我们直接暴力查找每个区间是否和别的区间相交,那么时间复杂度就是O(\(n^2\)),肯定是过不了的。考虑如何优化,通过题意,可以发现优化的关键在于区间相交的判定方式,对于任意两......
  • JINGWHALE ABCDE 概念模型系统设计建模法,用户画像进行场景化业务需求分析与归纳,帮你规
    JINGWHALE对此论文相关未知以及已知概念、定理、公式、图片等内容的感悟、分析、创新、创造等拥有作品著作权。未经JINGWHALE授权,禁止转载与商业使用。《一种基于概念模型思想的ABCDE系统设计建模法的研究与应用》张云龙(JINGWHALE数字科学艺术创新中心,浙江杭州,310......
  • CF Everyone Loves to Sleep 每个人都喜欢睡觉
    我这个蒟蒻又来做CF了我做的是“EveryoneLovestoSleep”“每个人都喜欢睡觉”Vlad,likeeveryoneelse,lovestosleepverymuch.EverydayVladhastodo n things,eachatacertaintime.Foreachofthesethings,hehasanalarmclockset,the i -......
  • ABC355
    A.WhoAtetheCake?模拟代码实现a,b=map(int,input().split())ifa==b:print(-1)else:print(6-a-b)B.Piano2模拟代码实现#include<bits/stdc++.h>#definerep(i,n)for(inti=0;i<(n);++i)usingnamespacestd;usingP=pair<......
  • ABC355 A ~ D
    A可能写麻烦了,但是至少它对了。#include<bits/stdc++.h>#definegtgetchar#defineptputchartypedeflonglongll;constintMAXN=2e5+5;constintmod=998244353;llread(){ llx=0,f=1;charch=gt(); while(ch<'0'||ch>'......
  • ABC355 D
    D-IntersectingIntervals我们思考如何计算不交的线段数量首先总的线段如果全部相交那么线段数应为n*(n-1)/2那么对于每对r[i]<l[i]都为不交的线段所以我们需要计算不交的线段数同时删去自己本身点击查看代码#include<bits/stdc++.h>#defineintlonglong#defineall(......
  • ABC346
    E题这题是春季测试涂色游戏的进阶版本,这个题的正确做法是”时光倒流“,因为是覆盖问题,所有从后面做倒着向前走,可能会更好但是这个题,我有一个做法是\(o(nlogn)\)的,我们先来考虑列,将列排序,按照时间来排序,对于每一行来说,每一列的染色时间都确定好了,我们可以二分为什么思考是二分?因......