AtCoder Beginner Contest 305 ABC D - Sleep Logの勉強
・参考:
Submission #42147989 - KYOCERA Programming Contest 2023(AtCoder Beginner Contest 305)
・考え方:前処理をしてクエリの中の処理を軽くする。二分探索を使うのでスライスにおけるAのi番目までの睡眠時間を前処理として行えば良い。プログラムの処理1では二分探索の位置が偶数だとansを引きすぎたり足しすぎたりしているのでそれを処理する。
・実装例:
import bisect n=int(input()) a=list(map(int,input().split())) #前処理。 #aに対応した睡眠時間をa_tにいれる。例えばはじめのテストケースで考えるとaのはじめからaの3番目(スライスにおける)までの睡眠時間はa_t[3]=480分。 a_t=[0] t=0 for i in range(1,n): if i%2==0: t+=a[i]-a[i-1] a_t.append(t) else: a_t.append(t) #print(a_t) #はじめのケースで[0, 0, 480, 480, 600, 600, 960] q=int(input()) for _ in range(q): l,r=map(int,input().split()) s=bisect.bisect_left(a,l) g=bisect.bisect_left(a,r) #処理1 ans=a_t[g]-a_t[s] #sからgまでの暫定的な睡眠時間。ただしsが偶数だと例えばl=250,s=2ではa_t[2]=480となり引きすぎてしまうので480-250の引きすぎた分を足す必要がある。gが偶数だと逆に足しすぎているので引く必要がある。 #print(s,g,a_t[s],a_t[g],ans) if s%2==0: ans+=a[s]-l #例えば、はじめのテストケースa[s]=a[2]=720でa_t[s]-l=720-480が引きすぎた睡眠時間になる。 if g%2==0: ans-=a[g]-r #例えばrが1920,g=6だとa[6]-r=2160-1920=240を引けばよい。 print(ans)