< iseeさんのAI生成コード置き場

AHCテンプレ

投稿者isee
言語PyPy3
更新日時 (JST)2026-10-14 23:00:43
サイズ8268 Byte
参照URL

日時はサーバーが記録したものです。更新すると更新日時が変わるので、不都合がある場合は新しく投稿してください。

import time
starttime = time.time()
currenttime = lambda: time.time() - starttime
import sys
# import random
import math

# ========== Codon 提出時はコメントアウトするゾーン

input = lambda: sys.stdin.readline().rstrip()
### デバッグ用
# 提出時・スコア計算時はデバッグモードオフにする
LOCAL = 'Main.py' not in sys.argv
DEBUG = LOCAL and 'score' not in sys.argv
SILENT = False  # デバッグ出力を黙らせる
DIR = 'D:/python/AtCoder/AHCxxx/'
TEST = '0000'

# デバッグ用入力
if DEBUG:
    f = open(DIR + 'tools/in/' + TEST + '.txt', 'r')
    # f = open('input.txt', 'r')
    sys.stdin = f

# デバッグ出力
def printdbg(*values: object, sep: str | None = ' ', end: str | None = '\n', file=None, flush=False):
    if DEBUG and not SILENT:
        print(*values, sep=sep, end=end, file=file, flush=flush)

# 出力に含めるデバッグ出力
def printdbgout(*values: object, sep: str | None = ' ', end: str | None = '\n', file=None, flush=False):
    print('# ', end='')
    print(*values, sep=sep, end=end, file=file, flush=flush)

# エラー出力
def printerr(*values: object, sep: str | None = ' ', end: str | None = '\n', file=None, flush=False):
    print(*values, sep=sep, end=end, file=sys.stderr, flush=flush)

# ========== Codon 提出時はコメントアウトするゾーン ここまで

# 乱数
# アルゴリズム:
#     https://ei1333.github.io/library/other/xor-shift.hpp.html
#     https://www.cepstrum.co.jp/hobby/xorshift/xorshift.html
# Codon対応済み
# 整数はやや低い値が出やすい。具体的には randrange(X) で 0 は X-1 の 1 + X / 2**32 倍くらい出やすい。

class XorShift32:
    """簡易 32 bit RNG
    
    非常に高速に動作する乱数生成器
    random = XorShift32() と宣言しておくことで、import random とほぼ同じ使い方が可能
    実数分布は一様分布 random(), uniform(a, b) のみ対応
    """
    MASK = (1 << 32) - 1
    R = 1 / (1 << 32)
    val: int

    def __init__(self, seed: int = 998244353) -> None:
        """初期 seed を指定して初期化
        
        Args:
            seed (int, optional): 初期 seed 、必ず非負整数にする
        """
        self.val = seed & XorShift32.MASK
    
    def _gen(self) -> int:
        # 乱数を更新し、現在の値を返す
        # # ↓ 超高速・短周期 (16,777,215)。質の保証はできない。
        # self.val ^= self.val << 7
        # self.val &= RNG.MASK
        # self.val ^= self.val >> 9
        # ↓ 高速・長周期 4,294,967,295 (2^32 - 1)
        self.val ^= self.val << 13
        self.val &= XorShift32.MASK
        self.val ^= self.val >> 17
        self.val ^= self.val << 5
        self.val &= XorShift32.MASK
        return self.val
    
    def randrange(self, start: int, stop: int=None, step: int=1) -> int:
        """range(start) / range(start, stop[, step]) 内の整数を 1 つ得る
        
        Args:
            start (int): 上限 または 下限
            stop (int, optional): 上限
            step (int, optional): 間隔
        
        Returns:
            int: 0 以上 start 未満 / start 以上 stop 未満 (step 間隔) のランダム整数
        """
        if stop is None:
            return self._gen() % start
        else:
            return start - self._gen() % ((start - stop) // step) * step
    
    def randint(self, a: int, b: int) -> int:
        """a 以上 b 以下の整数を 1 つ得る
        
        Args:
            a (int): 下限
            b (int): 上限
        
        Returns:
            int: a 以上 b 以下の乱数
        """
        return a + self._gen() % (b - a + 1)
    
    def random(self) -> float:
        """0 以上 1 未満の浮動小数点数を 1 つ得る

        Returns:
            float: 0 以上 1 未満の実数
        """
        return self._gen() * XorShift32.R
    
    def uniform(self, a: float, b: float) -> float:
        """a 以上 b 未満の浮動小数点数を 1 つ得る

        Returns:
            float: a 以上 b 未満の実数
        """
        return a + (b - a) * (self._gen() * XorShift32.R)
    
    def choice(self, seq):
        """seq からランダムに 1 つ要素を得る
        
        Args:
            seq (Sequence): 対象となる sequence
        
        Returns:
            Any: 選ばれた要素
        """
        return seq[self._gen() % (len(seq))]
    
    def choices(self, population, weights=None, cum_weights=None, k:int=1):
        """population からランダムに k 個要素を得る。各試行は独立。
        
        Args:
            population (Sequence): 対象となる sequence
            weight (List[float], optional): 各要素の出現率の重み
            cum_weight (List[float], optional): 各要素の出現率の重みの累積和
            k (int, optional): 選ぶ回数
        
        Returns:
            Any: 選ばれた要素のリスト
        """
        n = len(population)
        if weights is None and cum_weights is None:
            res = [population[0]] * k
            for i in range(k):
                res[i] = population[self._gen() % n]
            return res
        if cum_weights is None:
            cum_weights = list(weights)
            for i in range(1, n):
                cum_weights[i] += cum_weights[i - 1]
        total = cum_weights[n - 1]
        res = [population[0]] * k
        for i in range(k):
            r = (self._gen() * XorShift32.R) * total
            ok = n - 1
            ng = -1
            while ok - ng > 1:
                mid = (ok + ng) // 2
                if r < cum_weights[mid]:
                    ok = mid
                else:
                    ng = mid
            res[i] = population[ok]
        return res

    def shuffle(self, seq) -> None:
        """seq を直接書き換える形で混ぜる
        
        Args:
            seq (Sequence): 対象となる sequence
        """
        for i in range(len(seq)-1, 0, -1):
            n = self._gen() % (i+1)
            seq[i], seq[n] = seq[n], seq[i]
    
    def sample(self, population, k: int, counts=None):
        """poplation からランダムに重複なく k 個要素を得る

        count を使う場合、総和が 2^32 以上にならないように注意
        
        Args:
            population (Sequence): 対象となる sequence
            k (int): 抜き出す個数
            count (List[int], optional): 各要素の重複回数
        
        Returns:
            Any: 選ばれた要素のリスト
        """
        N = len(population)
        if counts is None:
            L = N - k
            S = set()
            for i in range(L, N):
                r = self._gen() % (i + 1)
                if r in S:
                    S.add(i)
                else:
                    S.add(r)
            idx = list(S)
            for i in range(k-1, 0, -1):
                j = self._gen() % (i + 1)
                idx[i], idx[j] = idx[j], idx[i]
            return [population[i] for i in idx]
        else:
            cum_counts = counts[:]
            for i in range(N-1):
                cum_counts[i+1] += cum_counts[i]
            M = cum_counts[-1]
            L = M - k
            S = set()
            for i in range(L, M):
                r = self._gen() % (i + 1)
                if r in S:
                    S.add(i)
                else:
                    S.add(r)
            idx = list(S)
            for i in range(k-1, 0, -1):
                j = self._gen() % (i + 1)
                idx[i], idx[j] = idx[j], idx[i]
            res = [population[0]]*k
            for i in range(k):
                r = idx[i]
                ok = N - 1
                ng = -1
                while ok - ng > 1:
                    mid = (ok + ng) // 2
                    if r < cum_counts[mid]:
                        ok = mid
                    else:
                        ng = mid
                res[i] = population[ok]
            return res
random = XorShift32()

### パラメータ


### ライブラリ


### 関数
def main():
    pass

### 入力・前処理
N = int(input())

### 計算・出力
main()