結果
| 問題 |
No.2025 Select $k$-th Submultiset
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-04-16 00:14:32 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 358 ms / 2,000 ms |
| コード長 | 5,101 bytes |
| コンパイル時間 | 192 ms |
| コンパイル使用メモリ | 82,228 KB |
| 実行使用メモリ | 107,240 KB |
| 最終ジャッジ日時 | 2025-04-16 00:15:56 |
| 合計ジャッジ時間 | 10,890 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 42 |
ソースコード
import sys
def main():
input = sys.stdin.read().split()
ptr = 0
N = int(input[ptr])
ptr += 1
L = int(input[ptr])
ptr += 1
c = list(map(int, input[ptr:ptr+N]))
ptr += N
Q = int(input[ptr])
ptr += 1
queries = []
for _ in range(Q):
queries.append(int(input[ptr]))
ptr += 1
# Precompute DP tables and prefix arrays
max_L = L
dp = [ [0]*(max_L +1) for _ in range(N+2) ] # 1-based to N
prefix_arrays = [None]*(N+2) # prefix_arrays[i] is for dp[i+1]
for i in range(N, 0, -1):
if i == N:
for s in range(0, max_L +1):
if s <= c[i-1]:
dp[i][s] = 1
else:
dp[i][s] = 0
elif i == N-1:
next_i = i +1
c_i = c[i-1]
c_next = c[next_i-1]
for s in range(0, max_L +1):
low = max(0, s - c_next)
high = min(c_i, s)
if low > high:
dp[i][s] = 0
else:
dp[i][s] = high - low +1
else:
next_i = i +1
# Compute prefix sum for dp[next_i]
prefix = [0]*(max_L +1)
prefix[0] = dp[next_i][0]
for s in range(1, max_L +1):
prefix[s] = prefix[s-1] + dp[next_i][s]
# Compute dp[i][s]
c_i = c[i-1]
for s in range(0, max_L +1):
a_max = min(c_i, s)
lower = s - a_max
if lower <0:
lower =0
if lower ==0:
sum_val = prefix[s] if s <= max_L else 0
else:
if s > max_L:
sum_val =0
else:
sum_val = prefix[s]
if lower-1 >=0:
sum_val -= prefix[lower-1]
dp[i][s] = sum_val
# Compute prefix array for i if i < N
if i < N:
next_i = i +1
prefix_arrays[i] = [0]*(max_L +1)
prefix_arrays[i][0] = dp[next_i][0]
for s in range(1, max_L +1):
prefix_arrays[i][s] = prefix_arrays[i][s-1] + dp[next_i][s]
# Process queries
total = dp[1][L]
for k in queries:
if k > total:
print(-1)
continue
remaining_k = k
remaining_sum = L
result = [0]*N
found = True
for current_i in range(N):
i = current_i +1 # 1-based
s = remaining_sum
if s <0:
found = False
break
if i == N:
# last element
if s > c[current_i] or remaining_k !=1:
found = False
break
result[current_i] = s
remaining_sum -= s
remaining_k =0
break
# Binary search for a_i
x_max = min(c[current_i], s)
low =0
high = x_max
ans = -1
prefix = prefix_arrays[i]
while low <= high:
mid = (low + high) //2
lower_t = s - x_max
upper_t = s - mid
if upper_t <0:
sum_ways =0
else:
if lower_t <0:
lower_t =0
if upper_t > max_L:
sum_ways =0
else:
sum_ways = prefix[upper_t]
if lower_t >0:
if lower_t-1 > max_L:
sum_ways -=0
else:
sum_ways -= prefix[lower_t -1]
if sum_ways >= remaining_k:
ans = mid
low = mid +1
else:
high = mid -1
if ans == -1:
found = False
break
# Compute sum_ways_gt
sum_ways_gt =0
if ans +1 <= x_max:
lower_t_gt = s - x_max
upper_t_gt = s - (ans +1)
if upper_t_gt <0:
sum_ways_gt =0
else:
if lower_t_gt <0:
lower_t_gt =0
if upper_t_gt > max_L:
sum_ways_gt =0
else:
sum_ways_gt = prefix[upper_t_gt]
if lower_t_gt >0:
if lower_t_gt -1 > max_L:
sum_ways_gt -=0
else:
sum_ways_gt -= prefix[lower_t_gt -1]
remaining_k -= sum_ways_gt
result[current_i] = ans
remaining_sum -= ans
if found and remaining_sum ==0 and remaining_k ==0:
print(' '.join(map(str, result)))
else:
print(-1)
if __name__ == "__main__":
main()
lam6er