結果
問題 | No.1097 Remainder Operation |
ユーザー | StanMarsh |
提出日時 | 2024-01-05 17:06:39 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 150 ms / 2,000 ms |
コード長 | 3,543 bytes |
コンパイル時間 | 255 ms |
コンパイル使用メモリ | 82,212 KB |
実行使用メモリ | 116,060 KB |
最終ジャッジ日時 | 2024-09-27 19:08:04 |
合計ジャッジ時間 | 5,644 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 33 ms
52,896 KB |
testcase_01 | AC | 34 ms
52,756 KB |
testcase_02 | AC | 36 ms
54,012 KB |
testcase_03 | AC | 38 ms
53,212 KB |
testcase_04 | AC | 36 ms
54,932 KB |
testcase_05 | AC | 37 ms
53,632 KB |
testcase_06 | AC | 38 ms
54,004 KB |
testcase_07 | AC | 59 ms
74,348 KB |
testcase_08 | AC | 59 ms
73,344 KB |
testcase_09 | AC | 57 ms
73,044 KB |
testcase_10 | AC | 56 ms
73,464 KB |
testcase_11 | AC | 56 ms
73,260 KB |
testcase_12 | AC | 112 ms
89,024 KB |
testcase_13 | AC | 108 ms
89,420 KB |
testcase_14 | AC | 109 ms
89,192 KB |
testcase_15 | AC | 113 ms
89,144 KB |
testcase_16 | AC | 114 ms
89,232 KB |
testcase_17 | AC | 112 ms
89,352 KB |
testcase_18 | AC | 143 ms
116,060 KB |
testcase_19 | AC | 141 ms
115,808 KB |
testcase_20 | AC | 141 ms
115,912 KB |
testcase_21 | AC | 150 ms
114,680 KB |
testcase_22 | AC | 143 ms
114,600 KB |
ソースコード
class CycleGetter(): def __init__(self,start,max_time): """ :param max_time: 移動回数 :param start: 初期条件 :return front: cycleまでの要素のリスト cycle: cycle内の要素のリスト end: cycle後の余った部分の要素のリスト cnt: cycle回数 """ p = start front, cycle, end = [], [], [] max_time+=1 cnt = 0 visit = {p:0} L, R =max_time,-1 P = [p] for i in range(1,max_time): p = lift(p) if p in visit: """ (L, R) = (サイクルに入るまでに移動した回数, サイクルの終端に着くまでに移動した回数) [6,2,3,4,0,1,2] ⇒ (L, R) = (1, 6) """ L, R = visit[p], i period = R-L break visit[p] = i P.append(p) front = P[:L] if L != max_time: cycle, end = P[L:R],P[L:L+(max_time-L)%period] cnt =(max_time-L)//period self.front,self.cycle,self.end,self.cnt = front, cycle, end, cnt def apply(self,time): """ :param time: time回進む :return: """ if time<len(self.front): return self.front[time] else: time-=len(self.front) time%=len(self.cycle) return self.cycle[time] def set_sum(self): """ 区間 [0,r) の累積和の求めるための前準備 """ def merge(x,y): return x+A[y] self.front_sum=[0] for a in self.front: self.front_sum.append(merge(self.front_sum[-1],a)) self.cycle_sum=[0] for a in self.cycle: self.cycle_sum.append(merge(self.cycle_sum[-1],a)) def sum(self,r): """ 区間 [0,r) の累積和の求める """ res=0 if r<=len(self.front): res+=self.front_sum[r] else: r-=len(self.front) p,q=r//len(self.cycle),r%len(self.cycle) res+=self.front_sum[-1] res+=self.cycle_sum[-1]*p+self.cycle_sum[q] return res def __getitem__(self, i): return self.apply(i) def __iter__(self): for i in range(max_time): yield self.apply(i) def __str__(self): res=[] for a in self: res.append(str(a)) return " ".join(res) ################################################################################ def example(): global input example = iter( """ 2 314159 141421 1 271828 """ .strip().split("\n")) input = lambda: next(example) ################################################################################ import sys input=sys.stdin.readline # example() N=int(input()) A=list(map(int, input().split())) ####################################### def lift(x): """ 写像を定義 """ return (x+A[x%N])%N start, max_time = 0, 10**13 CG=CycleGetter(start, max_time) """ 備考 スタート地点が変わる場合はダブリング スタート地点には作用がかかっていないため、スタート地点だけ性質が異なる場合がある点に注意 """ front,cycle,end,cnt = CG.front, CG.cycle, CG.end, CG.cnt ####################################### CG.set_sum() Q=int(input()) for _ in range(Q): K=int(input()) print(CG.sum(K))