結果
| 問題 | No.3397 Max Weighted Floor of Linear |
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2026-02-16 10:14:19 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
AC
|
| 実行時間 | 1,204 ms / 2,000 ms |
| コード長 | 3,153 bytes |
| 記録 | |
| コンパイル時間 | 340 ms |
| コンパイル使用メモリ | 82,464 KB |
| 実行使用メモリ | 89,396 KB |
| 最終ジャッジ日時 | 2026-02-16 10:14:41 |
| 合計ジャッジ時間 | 22,439 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 23 |
ソースコード
# -*- coding: utf-8 -*-
from __future__ import annotations
from dataclasses import dataclass
LL_MIN = -(1 << 63)
@dataclass(frozen=True)
class MwfData:
"""
sum : total sum (for concatenation)
best: maximum prefix value (or LL_MIN meaning "no valid prefix")
dx : length / shift amount (used to compute arg)
arg : argmax (smallest arg if tie)
"""
sum: int
best: int = LL_MIN
dx: int = 0
arg: int = 0
def __mul__(self, other: "MwfData") -> "MwfData":
S_MIN = LL_MIN
ssum = self.sum + other.sum
sdx = self.dx + other.dx
cand_l = self.best
cand_r = S_MIN if other.best == S_MIN else (self.sum + other.best)
if cand_l > cand_r:
return MwfData(ssum, cand_l, sdx, self.arg)
if cand_l < cand_r:
return MwfData(ssum, cand_r, sdx, self.dx + other.arg)
# tie
if cand_l == S_MIN:
return MwfData(ssum, S_MIN, sdx, 0)
return MwfData(ssum, cand_l, sdx, min(self.arg, self.dx + other.arg))
def __pow__(self, k: int) -> "MwfData":
# support: x ** k (k >= 0)
if not isinstance(k, int):
return NotImplemented
assert k >= 0
if k == 0:
return MwfData(0)
S_MIN = LL_MIN
ssum = self.sum * k
sdx = self.dx * k
if self.best == S_MIN:
return MwfData(ssum, S_MIN, sdx, 0)
if self.sum > 0:
sbest = (k - 1) * self.sum + self.best
sarg = (k - 1) * self.dx + self.arg
return MwfData(ssum, sbest, sdx, sarg)
return MwfData(ssum, self.best, sdx, self.arg)
def floor_prod(n: int, m: int, a: int, b: int, e, x, y):
"""
Requires:
- integers n,m,a,b with 0<=n, 0<m, 0<=a, 0<=b
- x,y,e are elements of a monoid-like structure:
* multiplication: t1 * t2
* power: t ** k for k>=0
"""
assert 0 <= n and 0 < m and 0 <= a and 0 <= b
c = (a * n + b) // m
pre = e
suf = e
while True:
p = a // m
a %= m
x = x * (y ** p)
q = b // m
b %= m
pre = pre * (y ** q)
c -= (p * n + q)
if c == 0:
return pre * (x ** n) * suf
d = (m * c - b - 1) // a + 1
suf = y * (x ** (n - d)) * suf
b = m - b - 1 + a
m, a = a, m
n = c - 1
c = d
x, y = y, x
def argmax_weighted_floor_of_linear(n: int, m: int, a: int, b: int, c: int, d: int) -> tuple[int, int]:
"""
argmwf(n,m,a,b,c,d) = (
max_{0<=i<n} floor((a*i+b)/m) + floor((c*i+d)/m),
argmax (smallest i if tie)
)
"""
assert n > 0 and m > 0
res: MwfData = floor_prod(
n, m, c, d,
MwfData(0),
MwfData(a, 0, 1, 0),
MwfData(b),
)
return res.best, res.arg
if __name__ == '__main__':
import sys
T = int(sys.stdin.readline())
for _ in range(T):
N, M, A, B, C, D = map(int, sys.stdin.readline().split())
max_val, _argmax = argmax_weighted_floor_of_linear(N, M, A, B, C, D)
sys.stdout.write(str(max_val) + '\n')