結果
| 問題 | 
                            No.836 じょうよ
                             | 
                    
| コンテスト | |
| ユーザー | 
                             | 
                    
| 提出日時 | 2021-03-15 21:05:13 | 
| 言語 | PyPy3  (7.3.15)  | 
                    
| 結果 | 
                             
                                AC
                                 
                             
                            
                         | 
                    
| 実行時間 | 96 ms / 1,000 ms | 
| コード長 | 3,526 bytes | 
| コンパイル時間 | 299 ms | 
| コンパイル使用メモリ | 82,432 KB | 
| 実行使用メモリ | 93,056 KB | 
| 最終ジャッジ日時 | 2024-11-07 09:55:11 | 
| 合計ジャッジ時間 | 4,200 ms | 
| 
                            ジャッジサーバーID (参考情報)  | 
                        judge2 / judge4 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| other | AC * 41 | 
ソースコード
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+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(
        """
30 30 11
        """
            .strip().split("\n"))
    input = lambda: next(example)
################################################################################
import sys
input=sys.stdin.readline
# example()
l,r,MOD=map(int,input().split())
#######################################
def lift(x):
    """ 写像を定義 """
    return (x+1)%MOD
start, max_time = l%MOD, r-l
CG=CycleGetter(start, max_time)
"""
備考
スタート地点が変わる場合はダブリング
スタート地点には作用がかかっていないため、スタート地点だけ性質が異なる場合がある点に注意
"""
front,cycle,end,cnt = CG.front, CG.cycle, CG.end, CG.cnt
#######################################
P=[0]*MOD
for x in front:
    P[x]+=1
for x in cycle:
    P[x]+=cnt
for x in end:
    P[x]+=1
print(*P,sep="\n")