fkphua3
Senior Member
check trường hợp root chưa bác,Em đếm mà không pass bác ạ
em for rồi đếm từ 1 tới n-1 rồi MOD là bác. Bài này nó lừa làm em bị + thêm 15 phút do submit sai 3 lần
check trường hợp root chưa bác,Em đếm mà không pass bác ạ
Đếm n -1 tới 1 thôi vì phải bỏ thằng root ra. Q3 Q4 khó vl ko hiểu nổiEm đếm mà không pass bác ạ
gang quáVl, cứ nghĩ là phải check từng tổ hợpđếm n-1 giai thừa thôi bác![]()

Xem tệp đính kèm 3074188
Việt Nam nói là làm, tuần rồi toy start lại giải đc 12 câu hard từ rating 2k1 -> 2k2đang củng cố cảnh giới để upsolve lên 2k4 chứ cũng gần nửa năm ko làm quên hết
1 tháng là giải được 50 câu rồi hí hí
Có vài trang bên ngoài rating các problem. Cái này chắc không chính xác lắm, mỗi trang số liệu khác nhau nên tham khảo thôidạo này e cày cuốc mãi mà gặp nhiều bài medium vẫn như gà mắc tóc.
Cho e xin web nào có rating của problems với bác?

class Solution:
def minOperations(self, word1: str, word2: str) -> int:
def minCost(i, j, reverse):
ans = int(reverse)
str1 = word1[i: j + 1] if not reverse else word1[i: j + 1][::-1]
str2 = word2[i: j + 1]
counter = defaultdict(int)
for i in range(len(str1)):
if str1[i] == str2[i]:
continue
if counter[(str2[i], str1[i])] > 0:
counter[(str2[i], str1[i])] -= 1
ans += 1
else:
counter[(str1[i], str2[i])] += 1
for key, val in counter.items():
ans += val
return ans
n = len(word1)
@lru_cache(None)
def dp(i):
if i == n:
return 0
ans = inf
for j in range(i, n):
cost = min(minCost(i, j, True), minCost(i, j, False))
ans = min(ans, cost + dp(j + 1))
return ans
return dp(0)
Thường bác làm chưa đc medium là do chưa nhuyễn mấy cái suy luận với là pattern recognition thôi. Medium thường chỉ cần suy luận khoảng 2 steps là ra và dùng data structure cơ bản thôidạo này e cày cuốc mãi mà gặp nhiều bài medium vẫn như gà mắc tóc.
Cho e xin web nào có rating của problems với bác?
Thường bác làm chưa đc medium là do chưa nhuyễn mấy cái suy luận với là pattern recognition thôi. Medium thường chỉ cần suy luận khoảng 2 steps là ra và dùng data structure cơ bản thôi
Cách luyện tốt nhất là luyện bài + 200 rating bác sẽ học được nhiều đó, làm dần sẽ quen.
Mình bị stuck ở cái tầm rank 2k1 rồi, mình làm bài hard thường sẽ nhìn ra pattern, nhìn ra sẽ dùng kĩ thuật gì nhưng hay bị miss cái key point nên cảm giác chỉ làm đc 7 80%. Chắc luyện thêm tầm 50 câu hard nữa sẽ unlock đc cái milestone này lên lại Guardian.rating
zerotrac.github.io
Như hôm qua 2 câu Q4 rõ ràng là ko khó, nhưng mà bằng cách nào đó trong contest mình quá focus vô Q3 nên hầu như skip luôn Q4. Nói chung là chỉ cần practice ko bỏ cuộc với chiến thuật hợp lí thôi.
Thực ra cái key point mà fen nói nó mới lại là mấu chốt với những bài hard. Nhìn ra được pattern theo mình chỉ chiếm 30-40% thôi. Ví dụ như việc nhìn ra được bài toán dùng bfs chẳng hạn, nhưng sau đó làm sao để optimize để tránh TLE, MLE nó lại là một câu chuyện khác nữa và khó hơn nhiều.
)) học xong quên rồi giờ bó tay
class Solution:
def findMedian(self, n: int, edges: List[List[int]], queries: List[List[int]]) -> List[int]:
graph = defaultdict(list)
for f, t, w in edges:
graph[f].append((t, w))
graph[t].append((f, w))
logVal = n.bit_length()
up = [[-1] * logVal for _ in range(n)]
depth = [0] * n
dist = [0] * n
def dfs(node, parent):
up[node][0] = parent
for j in range(1, logVal):
if up[node][j - 1] != -1:
up[node][j] = up[up[node][j - 1]][j - 1]
else:
break
for child, w in graph[node]:
if child == parent:
continue
dist[child] = dist[node] + w
depth[child] = depth[node] + 1
dfs(child, node)
dfs(0, -1)
def lca(u, v):
if depth[u] < depth[v]:
u, v = v, u
diff = depth[u] - depth[v]
for i in range(logVal - 1, -1, -1):
if diff & (1 << i):
u = up[u][i]
if u == v:
return u
for i in range(logVal - 1, -1, -1):
if up[u][i] != -1 and up[u][i] != up[v][i]:
u = up[u][i]
v = up[v][i]
return up[u][0]
def lift(u, k):
for i in range(logVal - 1, -1, -1):
if u == -1:
break
if k & (1 << i):
u = up[u][i]
return u
ans = []
for u, v in queries:
if u == v:
ans.append(u)
continue
w = lca(u, v)
totalPathWeight = dist[u] + dist[v] - 2 * dist[w]
halfTotalWeight = totalPathWeight / 2.0
distUToW = dist[u] - dist[w]
# The weighted median node will always be on the path from u to v.
# We can determine if it's on the u -> LCA segment or LCA -> v segment.
if halfTotalWeight <= distUToW:
# The median node is on the path from u to w (LCA)
# We need to find the node 'x' such that dist(u, x) >= halfTotalWeight.
# We want the 'x' that is closest to 'u' while satisfying this,
# meaning we're looking for the smallest 'k' (steps to lift u).
low, high = 0, depth[u] - depth[w]
stepsToLiftU = high # Initialize with a value that will be updated
while low <= high:
midK = (low + high) // 2
liftedNode = lift(u, midK)
currentDistFromU = dist[u] - dist[liftedNode]
if currentDistFromU >= halfTotalWeight:
stepsToLiftU = midK
high = midK - 1
else:
low = midK + 1
medianNode = lift(u, stepsToLiftU)
else:
# The median node is on the path from w (LCA) to v
# The cumulative weight from u to w is already 'distUToW'.
# We need 'halfTotalWeight - distUToW' more distance from w towards v.
# Let this be 'remainingWeightFromW'.
# We are looking for node 'x' on w -> v such that dist(w, x) >= remainingWeightFromW.
# This 'x' is found by lifting 'v' up.
# We need to find 'k' steps to lift 'v' such that:
# currentDistFromUToNode = dist(u, w) + dist(w, lift(v, k)) >= halfTotalWeight
# This simplifies to: distUToW + (dist[lift(v, k)] - dist[w]) >= halfTotalWeight
# Or, dist[u] + dist[lift(v, k)] - 2 * dist[w] >= halfTotalWeight
low, high = 0, depth[v] - depth[w]
stepsToLiftV = 0 # Initialize with 0 steps (node v itself)
while low <= high:
midK = (low + high) // 2
liftedNode = lift(v, midK)
currentDistFromUToNode = dist[u] + dist[liftedNode] - 2 * dist[w]
if currentDistFromUToNode >= halfTotalWeight:
stepsToLiftV = midK
high = midK - 1
else:
low = midK + 1
# After the loop, `stepsToLiftV` will hold the minimal steps to lift `v`
# such that `lift(v, stepsToLiftV)` is a candidate for the median.
# We need the node corresponding to this `stepsToLiftV`.
medianNode = lift(v, stepsToLiftV)
ans.append(medianNode)
return ans