結果
問題 | No.1778 括弧列クエリ / Bracketed Sequence Query |
ユーザー |
![]() |
提出日時 | 2021-12-07 02:31:02 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,838 ms / 2,000 ms |
コード長 | 2,282 bytes |
コンパイル時間 | 155 ms |
コンパイル使用メモリ | 82,304 KB |
実行使用メモリ | 230,204 KB |
最終ジャッジ日時 | 2024-07-07 10:12:18 |
合計ジャッジ時間 | 31,327 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 27 |
ソースコード
#LCA(最近共通祖先)#距離や間に挟まれているかも判定可能import collectionsimport syssys.setrecursionlimit(10**7)# N: 頂点数# G[v]: 頂点vの子頂点 (親頂点は含む)# Euler Tour の構築N,Q = map(int, input().split())N+=2pair = [0]*(N)S = list('('+input()+')')G = [[] for _ in range(N)]d = collections.deque()dn = collections.deque()d.append('x')d.append('x')for i in range(len(S)):if i>0 and S[i-1]=='(' and S[i]=='(':G[i].append(i-1)G[i-1].append(i)if i>0 and S[i-1]==')' and S[i]=='(':G[dn[-1]].append(i)G[i].append(dn[-1])d.append(S[i])dn.append(i)if d[-2]=='(' and d[-1]==')':d.pop()d.pop()l = dn.pop()r = dn.pop()pair[l]=rpair[r]=lG[l].append(r)G[r].append(l)S = []F = [0]*Ndepth = [0]*Ndef dfs(v, d , p):F[v] = len(S)depth[v] = dS.append(v)for n in G[v]:if p!=n:dfs(n, d+1, v)S.append(v)dfs(0, 0, -1)# 存在しない範囲は深さが他よりも大きくなるようにするINF = (10**18, 0)# LCAを計算するクエリの前計算M = 2*NM0 = 2**(M-1).bit_length()data = [INF]*(2*M0)for i, v in enumerate(S):data[M0-1+i] = (depth[v], i)for i in range(M0-2, -1, -1):data[i] = min(data[2*i+1], data[2*i+2])# LCAの計算 (generatorで最小値を求める)def _query(a, b):yield INFa += M0; b += M0while a < b:if b & 1:b -= 1yield data[b-1]if a & 1:yield data[a-1]a += 1a >>= 1; b >>= 1# LCAの計算 (外から呼び出す関数)def query(u, v):fu = F[u]; fv = F[v]if fu > fv:fu, fv = fv, fureturn S[min(_query(fu, fv+1))[1]]# 2点間の距離def distance(u, v):return depth[u]+depth[v]-2*depth[query(u, v)]# aがuとvの間に挟まれているかdef isOnPath(u,v,a):return distance(u,v)==distance(u,a)+distance(v,a)for _ in range(Q):x,y = map(int,input().split())if x==y:print(min(x,pair[x]),max(x,pair[x]))else:l = query(x,y)if l == 0:print(-1)else:print(min(l,pair[l]),max(l,pair[l]))