A - 累進課税シミュレーション / Progressive Taxation Simulation Editorial by admin
GPT 5.2 High概要
所得 \(S_i\) に対して、境界 \(L\) を境に税率が変わる累進課税をその定義通りに計算し、各人の税額 \(T_i\) を出力します。
考察
この問題のポイントは、所得を「最初の \(L\) 円まで」と「\(L\) 円を超える部分」に分けて税率を掛け、最後に合計してから一度だけ切り捨て(床)を行うことです。
- \(S \le L\) のときは単純に \(T=\left\lfloor \dfrac{S\cdot P}{100}\right\rfloor\)。
- \(S > L\) のときは
\(T=\left\lfloor \dfrac{L\cdot P+(S-L)\cdot Q}{100}\right\rfloor\)。
ここで注意すべきなのが、「\(L\cdot P\) と \((S-L)\cdot Q\) をそれぞれ \(100\) で割って切り捨てた後に足す」のではない、という点です。
例えば(極端な例ですが)\(L=1, P=50, Q=50, S=2\) だと、
- 正しい計算:\(\left\lfloor \dfrac{1\cdot 50 + 1\cdot 50}{100}\right\rfloor=\lfloor 1 \rfloor = 1\)
- 誤った分割切り捨て:\(\left\lfloor \dfrac{50}{100}\right\rfloor+\left\lfloor \dfrac{50}{100}\right\rfloor = 0+0=0\)
となり結果が変わってしまいます。よって「合計してから \(//100\)」が必須です。
また、\(N\le 10^5\) なので各人について \(O(1)\) で計算していけば十分間に合います。むしろ Python では入出力がボトルネックになりやすいので、高速入力(まとめ読み)を使うのが安全です。
アルゴリズム
各所得 \(S\) について次を行います。
- 低税率部分(最大 \(L\) まで)を
\(low = \min(S, L)\) - 高税率部分(\(L\) を超えた分)を
\(high = \max(0, S-L)\) - 税額を定義通りに一括で切り捨てて
\(tax = \dfrac{low\cdot P + high\cdot Q}{100}\) の床、すなわち
tax = (low * P + high * Q) // 100 - これを全員分出力する。
計算量
- 時間計算量: \(O(N)\)(各人 \(O(1)\) 計算)
- 空間計算量: \(O(N)\)(出力用に結果を配列に保持するため)
実装のポイント
切り捨ては必ず
(low * P + high * Q) // 100のように「合計後に一度だけ」行います。値の範囲は \(S,L\le 10^9\)、税率 \(\le 100\) なので、積は最大でも \(10^{11}\) 程度です。Python の整数なら安全ですが、他言語では 64bit 整数(
long long)を使うのが無難です。\(N=10^5\) では
input()を繰り返すより、sys.stdin.buffer.read()でまとめて読み、最後に"\n".join(...)でまとめて出力すると高速です。ソースコード
import sys
def main():
data = list(map(int, sys.stdin.buffer.read().split()))
N, L, P, Q = data[0], data[1], data[2], data[3]
res = []
idx = 4
for _ in range(N):
s = data[idx]
idx += 1
low = s if s <= L else L
high = 0 if s <= L else s - L
tax = (low * P + high * Q) // 100
res.append(str(tax))
sys.stdout.write("\n".join(res))
if __name__ == "__main__":
main()
この解説は gpt-5.2-high によって生成されました。
posted:
last update: