結果
| 問題 | No.3720 Balanced Reduction |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-09-18 22:26:57 |
| 言語 | PyPy3 (7.3.23 + ACL) |
| 結果 |
AC
不安定
|
| 実行時間 | 535 ms / 2,000 ms |
| + 144µs | |
| コード長 | 4,349 bytes |
| 記録 | |
| コンパイル時間 | 183 ms |
| コンパイル使用メモリ | 82,304 KB |
| 実行使用メモリ | 155,772 KB |
| 最終ジャッジ日時 | 2026-09-18 22:27:03 |
| 合計ジャッジ時間 | 5,240 ms |
|
ジャッジサーバーID (参考情報) |
judge1_0 / judge2_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 16 |
ソースコード
# haru: pypy
import sys
input = sys.stdin.readline
II = lambda : int(input())
MI = lambda : map(int, input().split())
LI = lambda : [int(a) for a in input().split()]
SI = lambda : input().rstrip()
LLI = lambda n : [[int(a) for a in input().split()] for _ in range(n)]
LSI = lambda n : [input().rstrip() for _ in range(n)]
MI_1 = lambda : map(lambda x:int(x)-1, input().split())
LI_1 = lambda : [int(a)-1 for a in input().split()]
mod = 998244353
inf = 1001001001001001001
ordalp = lambda s : ord(s)-65 if s.isupper() else ord(s)-97
ordallalp = lambda s : ord(s)-39 if s.isupper() else ord(s)-97
yes = lambda : print("Yes")
no = lambda : print("No")
yn = lambda flag : print("Yes" if flag else "No")
prinf = lambda ans : print(ans if ans < 1000001001001001001 else -1)
alplow = "abcdefghijklmnopqrstuvwxyz"
alpup = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
alpall = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
URDL = {'U':(-1,0), 'R':(0,1), 'D':(1,0), 'L':(0,-1)}
DIR_4 = [[-1,0],[0,1],[1,0],[0,-1]]
DIR_8 = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]]
DIR_BISHOP = [[-1,1],[1,1],[1,-1],[-1,-1]]
prime60 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59]
sys.set_int_max_str_digits(0)
# sys.setrecursionlimit(10**6)
# import pypyjit
# pypyjit.set_param('max_unroll_recursion=-1')
from collections import defaultdict,deque
from heapq import heappop,heappush
from bisect import bisect_left,bisect_right
DD = defaultdict
BSL = bisect_left
BSR = bisect_right
"""
namori
k <= x <= 2k を減らせる
うーん、
"""
n, k = MI()
a = LI()
d = [0] * n
e = [[] for i in range(n)]
for i in range(n):
u, v = MI_1()
e[u].append(v)
e[v].append(u)
d[u] += 1
d[v] += 1
que = [i for i in range(n) if d[i] == 1]
ans = 0
for u in que:
for v in e[u]:
if d[v] > 0:
p = v
break
a[p] -= a[u]
if a[p] < 0:
print(-1)
exit()
d[u] = 0
d[p] -= 1
if d[p] == 1:
que.append(p)
if 0 < a[u] < k:
print(-1)
exit()
else:
# たぶんあってる
ans += ((a[u] - 1) // (2 * k)) + 1
# que に入っていない頂点が cycle
for i in range(n):
if d[i] > 0:
u = i
break
# print(ans, a)
s = u
cyc = []
p = -1
while True:
# print(u)
cyc.append(u)
for v in e[u]:
if d[v] > 0 and v != p:
nxt = v
break
if nxt == s:
break
p, u = u, nxt
b = [a[u] for u in cyc]
# print(ans, b)
m = len(b)
"""
b[i] = x[i-1] + x[i] とする
x[i] は
d[i] + t : even
d[i] - t : odd
"""
d = [0] * m
for i in range(1, m):
d[i] = b[i] - d[i - 1]
sgn = [1, -1]
if m % 2 == 1:
# b[0] = 2 t + d[m - 1]
t = b[0] - d[-1]
if t % 2 == 1:
print(-1)
exit()
t //= 2
d = [d[i] + (t * sgn[i & 1]) for i in range(m)]
# これ回数
for i in range(m):
if d[i] < 0 or 0 < d[i] < k:
print(-1)
exit()
else:
ans += ((d[i] - 1) // (2 * k)) + 1
print(ans)
exit()
if d[-1] != b[0]:
print(-1)
exit()
# 最小化がひつようめう
# for i in ra
"""
b[i] = x[i-1] + x[i] とする
x[i] は
d[i] + t : even
d[i] - t : odd
t - (-d[i])
t の範囲 : p, [p+k, q-k], q
"""
def calc(t):
nd = [d[i] + (t * sgn[i & 1]) for i in range(m)]
tmp = 0
for i in range(m):
if nd[i] < 0 or 0 < nd[i] < k:
return inf
else:
tmp += ((nd[i] - 1) // (2 * k)) + 1
return tmp
p = max(-d[i] for i in range(0, m, 2))
q = min(d[i] for i in range(1, m, 2))
tmp = min(calc(p), calc(q))
p += k
q -= k
if q < p:
prinf(ans + tmp)
exit()
# そうではない時は p <= t <= q の実行可能解で
# 区間に収まるのは保証されている
# 適当に変わる位置だけ見れば良さそうかな
q = min(q + 1, p + 2 * k) # [p, q)
eve = DD(int)
now = calc(p)
for i in range(m):
if i % 2 == 0:
# even
# d[i] + t // 2k が変化する
c = (1 - d[i]) % (2 * k)
else:
c = d[i] % (2 * k)
# p よりあとのはじめ
c = p + 1 + (c - (p + 1)) % (2 * k)
if c < q:
eve[c] += sgn[i & 1]
for _, d in sorted(eve.items()):
now += d
tmp = min(tmp, now)
prinf(ans + tmp)