結果

問題 No.1097 Remainder Operation
ユーザー StanMarshStanMarsh
提出日時 2024-01-05 17:06:39
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 172 ms / 2,000 ms
コード長 3,543 bytes
コンパイル時間 368 ms
コンパイル使用メモリ 81,828 KB
実行使用メモリ 115,652 KB
最終ジャッジ日時 2024-01-05 17:06:45
合計ジャッジ時間 5,584 ms
ジャッジサーバーID
(参考情報)
judge14 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 36 ms
53,460 KB
testcase_01 AC 35 ms
53,460 KB
testcase_02 AC 37 ms
53,460 KB
testcase_03 AC 36 ms
53,460 KB
testcase_04 AC 36 ms
53,460 KB
testcase_05 AC 36 ms
53,460 KB
testcase_06 AC 36 ms
53,460 KB
testcase_07 AC 59 ms
72,788 KB
testcase_08 AC 59 ms
72,788 KB
testcase_09 AC 58 ms
72,788 KB
testcase_10 AC 58 ms
72,788 KB
testcase_11 AC 59 ms
72,788 KB
testcase_12 AC 116 ms
89,056 KB
testcase_13 AC 116 ms
88,928 KB
testcase_14 AC 119 ms
89,056 KB
testcase_15 AC 146 ms
89,052 KB
testcase_16 AC 119 ms
88,928 KB
testcase_17 AC 117 ms
89,144 KB
testcase_18 AC 144 ms
115,652 KB
testcase_19 AC 144 ms
115,648 KB
testcase_20 AC 144 ms
115,648 KB
testcase_21 AC 147 ms
114,368 KB
testcase_22 AC 172 ms
114,368 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

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))
0