結果
| 問題 |
No.650 行列木クエリ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-09-09 00:20:32 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 5,275 bytes |
| コンパイル時間 | 338 ms |
| コンパイル使用メモリ | 82,424 KB |
| 実行使用メモリ | 141,524 KB |
| 最終ジャッジ日時 | 2025-09-09 00:20:37 |
| 合計ジャッジ時間 | 5,043 ms |
|
ジャッジサーバーID (参考情報) |
judge / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 1 |
| other | AC * 1 TLE * 1 -- * 8 |
ソースコード
import sys
sys.setrecursionlimit(10**7)
input = sys.stdin.readline
class HLDecomposition:
def __init__(self, N, G, op, e):
self.N = N
self.G = G
self.op = op
self.e = e
self.parent = [-1]*N
self.depth = [0]*N
self.size = [0]*N
self.heavy = [-1]*N
self.__build_1(0)
self.top = [0]*N
self.HLD_G = [0]
self.__build_2(0)
self.HLD_G = self.HLD_G[::-1]
self.node_w = [self.e.copy() for _ in range(N)]
self.node = [N-1]*N
self.__make_tree()
def set(self, v, w, weight):
if self.parent[w]==v:
v, w = w, v
elif self.parent[v]!=w:
return False
vi, wi = self.node[v], self.node[w]
self.Tree.set(vi, weight)
def prod(self, l, r):
sml, smr = self.e, self.e
while True:
li, ri = self.node[l], self.node[r]
# print(l, r)
if self.top[l]==self.top[r]:
if self.depth[l]>self.depth[r]:
sml = self.op(sml, self.Tree.prod(li, ri))
else:
smr = self.op(self.Tree.prod(ri, li), smr)
return self.op(sml, smr)
else:
l_top, r_top = self.top[l], self.top[r]
if self.depth[l_top]>self.depth[r_top]:
sml = self.op(sml, self.Tree.prod(li, self.node[l_top]+1))
l = self.parent[l_top]
else:
smr = self.op(self.Tree.prod(ri, self.node[r_top]+1), smr)
r = self.parent[r_top]
def __build_1(self, v0):
for v1, _ in self.G[v0]:
if v1==self.parent[v0]:
continue
else:
self.parent[v1] = v0
self.depth[v1] = self.depth[v0]+1
self.size[v0] += self.__build_1(v1)
temp = self.heavy[v0]
if temp==-1 or self.size[temp]<self.size[v1]:
self.heavy[v0] = v1
self.size[v0] += 1
return self.size[v0]
def __build_2(self, v0):
if self.heavy[v0]!=-1:
v1 = self.heavy[v0]
self.top[v1] = self.top[v0]
self.HLD_G.append(v1)
self.__build_2(v1)
for v1, _ in self.G[v0]:
if v1==self.heavy[v0] or v1==self.parent[v0]:
continue
else:
self.top[v1] = v1
self.HLD_G.append(v1)
self.__build_2(v1)
def __make_tree(self):
for i, v0 in enumerate(self.HLD_G[:-1]):
for v1, w in self.G[v0]:
if v1==self.parent[v0]:
self.node_w[i] = w
break
self.node[v0] = i
self.Tree = SegmentTree(self.op, self.e, self.N, self.node_w)
class SegmentTree:
def __init__(self, op, e, n, List=None):
self.op = op
self.e = e
self.n = n
self.log_2 = (self.n-1).bit_length()
self.size = 1<<self.log_2
self.data = [e for _ in range(2*self.size)]
if not List is None:
for i in range(self.n):
self.data[i+self.size] = List[i]
for i in range(self.size-1, 0, -1):
self.data[i] = self.op(self.data[i<<1], self.data[(i<<1)|1])
def prod(self, l, r):
sml, smr = self.e, self.e
l += self.size
r += self.size
while l<r:
if l&1==1:
sml = self.op(sml, self.data[l])
l += 1
if r&1==1:
r -= 1
smr = self.op(self.data[r], smr)
l >>= 1
r >>= 1
return self.op(sml, smr)
def set(self, i, x):
i += self.size
self.data[i] = x
while i>1:
i >>= 1
self.data[i] = self.op(self.data[i<<1], self.data[(i<<1)|1])
def get(self, i):
return self.data[i+self.size]
def all_prod(self):
return self.data[1]
def max_right(self, l, f):
if l==self.n:
return self.n
l += self.size
sm = self.e
while True:
while l&1==0:
l >>= 1
if not f(self.op(sm, self.data[l])):
while l<self.size:
l <<= 1
if f(self.op(sm, self.data[l])):
sm = self.op(sm, self.data[l])
l += 1
return l-self.size
else:
sm = self.op(sm, self.data[l])
l += 1
if l&(-l)==l:
return self.n
def min_left(self, r, f):
if r==0:
return 0
r += self.size
sm = self.e
while True:
r -= 1
while r&1==1 and r>1:
r >>= 1
if not f(self.op(self.data[r], sm)):
while r<self.size:
r <<= 1
r += 1
if f(self.op(self.data[r], sm)):
sm = self.op(self.data[r], sm)
r -= 1
return r+1-self.size
else:
sm = self.op(self.data[r], sm)
if r&-r==r:
return 0
n = int(input())
e = [[1, 0], [0, 1]]
G = [[] for _ in range(n)]
UV = [tuple(map(int, input().split())) for _ in range(n-1)]
for i in range(n-1):
u, v = UV[i]
G[u].append((v, e.copy()))
G[v].append((u, e.copy()))
def op(R, L):
return [[L[0][0]*R[0][0]+L[0][1]*R[1][0], L[0][0]*R[0][1]+L[0][1]*R[1][1]], [L[1][0]*R[0][0]+L[1][1]*R[1][0], L[1][0]*R[0][1]+L[1][1]*R[1][1]]]
HL = HLDecomposition(n, G, op, e)
for _ in range(int(input())):
it = map(str, input().split())
if next(it)=='x':
idx, a, b, c, d = map(int, list(it))
HL.set(UV[idx][0], UV[idx][1], [[a, b], [c, d]])
else:
u, v = map(int, list(it))
x = HL.prod(v, u)
answer = []
for i in range(2):
for j in range(2):
answer.append(x[i][j])
print(*answer)