結果
問題 |
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()