結果
| 問題 |
No.2025 Select $k$-th Submultiset
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-05-15 02:06:49 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 539 ms / 2,000 ms |
| コード長 | 4,253 bytes |
| コンパイル時間 | 544 ms |
| コンパイル使用メモリ | 82,304 KB |
| 実行使用メモリ | 104,900 KB |
| 最終ジャッジ日時 | 2025-05-15 02:07:09 |
| 合計ジャッジ時間 | 17,245 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 42 |
ソースコード
import sys
def main():
data = sys.stdin.read().strip().split()
if not data:
return
it = iter(data)
N = int(next(it)); L_val = int(next(it))
c = [int(next(it)) for _ in range(N)]
Q = int(next(it))
queries = [int(next(it)) for _ in range(Q)]
L = L_val
dp = [[0] * (L + 1) for _ in range(N + 2)]
prefix = [[0] * (L + 1) for _ in range(N + 2)]
dp[N + 1][0] = 1
for j in range(0, L + 1):
if j == 0:
prefix[N + 1][j] = dp[N + 1][j]
else:
prefix[N + 1][j] = prefix[N + 1][j - 1] + dp[N + 1][j]
for i in range(N, 0, -1):
current_c = c[i - 1]
for j in range(0, L + 1):
a_max = min(current_c, j)
low_bound_index = j - a_max - 1
if low_bound_index < 0:
dp[i][j] = prefix[i + 1][j] if j <= L else prefix[i + 1][L]
else:
if j > L:
part1 = prefix[i + 1][L]
else:
part1 = prefix[i + 1][j]
if low_bound_index > L:
part2 = prefix[i + 1][L]
else:
part2 = prefix[i + 1][low_bound_index]
dp[i][j] = part1 - part2
for j in range(0, L + 1):
if j == 0:
prefix[i][j] = dp[i][j]
else:
prefix[i][j] = prefix[i][j - 1] + dp[i][j]
out_lines = []
for k_query in queries:
remaining = L
current_k = k_query
freq = [0] * (N + 1)
valid = True
for i in range(1, N + 1):
a_max = min(c[i - 1], remaining)
total_ways = dp[i][remaining]
if current_k > total_ways:
valid = False
break
low_bound_index = remaining - a_max - 1
low = 0
high = a_max + 1
candidate_x = 0
while low <= high:
mid = (low + high) // 2
if mid == 0:
cum_mid = 0
else:
end_index = remaining - a_max + mid - 1
end_index = min(end_index, L)
end_index = max(end_index, -1)
if end_index < 0:
cum_end_index = 0
else:
cum_end_index = prefix[i + 1][end_index]
if low_bound_index < 0:
cum_mid = cum_end_index
else:
cum_low_index = min(low_bound_index, L)
cum_low_index = max(cum_low_index, -1)
if cum_low_index < 0:
cum_low_val = 0
else:
cum_low_val = prefix[i + 1][cum_low_index]
cum_mid = cum_end_index - cum_low_val
if cum_mid < current_k:
candidate_x = mid
low = mid + 1
else:
high = mid - 1
candidate = a_max - candidate_x
if candidate_x == 0:
cum_candidate = 0
else:
end_idx = remaining - a_max + candidate_x - 1
end_idx = min(end_idx, L)
end_idx = max(end_idx, -1)
if end_idx < 0:
val1 = 0
else:
val1 = prefix[i + 1][end_idx]
if low_bound_index < 0:
val2 = 0
else:
low_idx = min(low_bound_index, L)
low_idx = max(low_idx, -1)
if low_idx < 0:
val2 = 0
else:
val2 = prefix[i + 1][low_idx]
cum_candidate = val1 - val2
current_k -= cum_candidate
freq[i] = candidate
remaining -= candidate
if not valid or remaining != 0:
out_lines.append("-1")
else:
out_str = " ".join(str(freq[i]) for i in range(1, N + 1))
out_lines.append(out_str)
for line in out_lines:
print(line)
if __name__ == '__main__':
main()