백준 2927 남극탐험 Python
2025년 01월 30일
#algorithm
https://www.acmicpc.net/problem/2927
트리에서 노드 연결, 단일 업데이트, 구간합 쿼리를 수행하는 문제이다. 연결 여부는 union-find로 관리하고, 먼저 모든 연결 쿼리를 수행하여 HLD를 해준다. 이후, 순서대로 쿼리를 처리하면 된다. HLD 과정에서, 트리가 여러개로 분할된 경우도 존재하기 때문에 방문하지 않은 노드에 대해 모두 dfs를 실행해야 한다.
import sys
sys.setrecursionlimit(10**6)
rl = sys.stdin.readline
N = int(rl())
ns = list(map(int, rl().split()))
tree = [0] * (N*4)
def tree_update(node, l, r, x, v):
if x < l or r < x: return tree[node]
if l == r:
tree[node] = v
return tree[node]
mid = (l+r) // 2
tree[node*2] = tree_update(node*2, l, mid, x, v)
tree[node*2+1] = tree_update(node*2+1, mid+1, r, x, v)
tree[node] = tree[node*2] + tree[node*2+1]
return tree[node]
def tree_query(node, l, r, s, e):
if r < s or e < l: return 0
if s <= l and r <= e: return tree[node]
mid = (l+r) // 2
return tree_query(node*2, l, mid, s, e) + tree_query(node*2+1, mid+1, r, s, e)
def dfs(x):
vst[x] = 1
for nx in es[x]:
if vst[nx]: continue
vst[nx] = 1
g[x].append(nx)
dfs(nx)
def dfs1(x):
sz[x] = 1
for i, nx in enumerate(g[x]):
par[nx] = x
dep[nx] = dep[x] + 1
dfs1(nx)
sz[x] += sz[nx]
if sz[g[x][0]] < sz[g[x][i]]:
g[x][0], g[x][i] = g[x][i], g[x][0]
pos = 0
def dfs2(x):
global pos
pos += 1
inc[x] = pos
for nx in g[x]:
top[nx] = top[x] if nx == g[x][0] else nx
dfs2(nx)
def query(a, b):
ret = 0
while top[a] != top[b]:
if dep[top[a]] < dep[top[b]]: a, b = b, a
at = top[a]
ret += tree_query(1, 1, N, inc[at], inc[a])
a = par[at]
if dep[a] > dep[b]: a, b = b, a
ret += tree_query(1, 1, N, inc[a], inc[b])
return ret
def findp(x):
if p[x] == x: return x
p[x] = findp(p[x])
return p[x]
def union(a, b):
a = findp(a)
b = findp(b)
if a < b: a, b = b, a
p[b] = a
Q = int(rl())
qs = []
es = [[] for _ in range(N+1)]
p = [i for i in range(N+1)]
vst = [0 for _ in range(N+1)]
g = [[] for _ in range(N+1)]
sz, dep, par, top, inc = [0]*(N+1), [0]*(N+1), [0]*(N+1), [0]*(N+1), [0]*(N+1)
for i in range(Q):
q, a, b = rl().split()
a, b = int(a), int(b)
if q == "bridge":
if findp(a) != findp(b):
union(a, b)
es[a].append(b)
es[b].append(a)
qs.append((q, a, b))
else:
qs.append((q, a, b))
for i in range(1, N+1):
if not vst[i]:
dfs(i); dfs1(i); dfs2(i)
for idx, v in enumerate(ns):
tree_update(1, 1, N, inc[idx+1], v)
p = [i for i in range(N+1)]
for q, a, b in qs:
if q == "bridge":
if findp(a) != findp(b):
union(a, b); print("yes")
else:
print("no")
elif q == "penguins":
tree_update(1, 1, N, inc[a], b)
else:
if findp(a) == findp(b):
print(query(a, b))
else:
print("impossible")관련 글
BOJ 25910 게이트웨이 정하기 python
문제 게이트웨이 정하기 풀이 비트 연산의 특징을 알아야 풀 수 있는 문제였다. 1. 임의의 노드에서 시작한 결과를 dp에 저장한다. 2. 각 비트를 0인 그룹과, 1인 그룹으로 나눈다.(temp에 1일 경우만 저장) 3. 모든 노드에 대해 헤더와 XOR연산으로 비용을 구한다. 4....
programmers 행렬과 연산 python
문제 행렬과 연산 풀이 표를 적당히 쪼개서 deque로 풀면 된다. 맨 왼쪽 열과 맨 오른쪽 열을 따로 저장해서 deque 2개를 만들고, 각 행의 인덱스를 저장한 deque를 만든다. 연산 시, q, leftq, rightq에 저장된 마지막 인덱스를 맨 앞으로 옮겨준다. 연산 시...
BOJ 16118 달빛 여우 python
문제 달빛 여우 풀이 먼저 일반적인 다익스트라 알고리즘으로 여우의 이동시간을 구해서 dp에 저장해준다. 늑대의 경우에는 빨리 이동해서 도착했을 때, 느리게 이동해서 도착했을 때의 시간을 따로 저장해야 한다. 두 dp를 비교해서 ans를 구한다. > 추가시간이 없는 문제라서 파이썬으...