結果
問題 | No.1914 Directed by Two Sequences |
ユーザー |
|
提出日時 | 2021-10-31 19:02:09 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,665 ms / 3,000 ms |
コード長 | 5,915 bytes |
コンパイル時間 | 1,121 ms |
コンパイル使用メモリ | 82,552 KB |
実行使用メモリ | 193,616 KB |
最終ジャッジ日時 | 2024-12-16 01:20:46 |
合計ジャッジ時間 | 58,408 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 38 |
ソースコード
class SegmentTree:def __init__(self, init_val, segfunc, ide_ele):n = len(init_val)self.segfunc = segfuncself.ide_ele = ide_eleself.num = 1 << (n - 1).bit_length()self.tree = [ide_ele] * 2 * self.numself.size = nfor i in range(n):self.tree[self.num + i] = init_val[i]for i in range(self.num - 1, 0, -1):self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])def update(self, k, x):k += self.numself.tree[k] = xwhile k > 1:k >>= 1self.tree[k] = self.segfunc(self.tree[2*k], self.tree[2*k+1])def query(self, l, r):if r==self.size:r = self.numres = self.ide_elel += self.numr += self.numright = []while l < r:if l & 1:res = self.segfunc(res, self.tree[l])l += 1if r & 1:right.append(self.tree[r-1])l >>= 1r >>= 1for e in right[::-1]:res = self.segfunc(res,e)return resdef solve(N,A,B,M,E):from collections import dequeA = [a-1 for a in A]B = [b-1 for b in B]res = set()edge = [[] for v in range(N)]for u,v in E:edge[u-1].append(v-1)edge[v-1].append(u-1)group = [-1 for v in range(N)]for v in range(N):mex = [False for i in range(len(edge[v])+1)]for nv in edge[v]:if nv < v and group[nv] < len(mex):mex[group[nv]] = Truefor i in range(len(mex)):if not mex[i]:group[v] = ibreakn = max(group) + 1clique = [[] for g in range(n)]for v in range(N):clique[group[v]].append(v)def direct(i,j):if i < j:return A[i] < B[j]else:return B[i] < A[j]def merge(a,b):res = []bi = 0for ai in range(len(a)):while bi<len(b) and direct(b[bi],a[ai]):res.append(b[bi])bi += 1res.append(a[ai])res += b[bi:]return residx = [-1 for v in range(N)]for g in range(n):deq = deque([[v] for v in clique[g]])while 1 < len(deq):a = deq.popleft()b = deq.popleft()deq.append(merge(a,b))clique[g] = deq[0]for i in range(len(clique[g])):idx[clique[g][i]] = ifor u,v in zip(clique[g],clique[g][1:]):res.add((u,v))memo_to = [N for v in range(N)]memo_from = [-1 for v in range(N)]ci = [i for i in range(n)]ci.sort(lambda g:len(clique[g]))idx_on_ci = [-1 for i in range(n)]for i in range(n):idx_on_ci[ci[i]] = iban = [[] for v in range(N)]Vs = []for i in range(n):target = ci[i]Vs += clique[target]Vs.sort()val = sorted([A[v] for v in Vs]+[B[v] for v in Vs])comp = {e:i for i,e in enumerate(val)}for nv in clique[target]:for v in edge[nv]:if idx_on_ci[group[v]] <= i:ban[v].append(nv)seg_to_large = SegmentTree([N]*len(comp),min,N)seg_to_small = SegmentTree([N]*len(comp),min,N)seg_from_large = SegmentTree([-1]*len(comp),max,-1)seg_from_small = SegmentTree([-1]*len(comp),max,-1)k = len(comp)for v in Vs[::-1]:for nv in ban[v]:if v < nv:seg_to_large.update(comp[B[nv]],N)memo_to[v] = min(memo_to[v],seg_to_large.query(comp[A[v]],k))for nv in ban[v]:if v < nv:seg_to_large.update(comp[B[nv]],idx[nv])if group[v]==target:seg_to_large.update(comp[B[v]],idx[v])for v in Vs:for nv in ban[v]:if nv < v:seg_to_small.update(comp[A[nv]],N)memo_to[v] = min(memo_to[v],seg_to_small.query(comp[B[v]],k))for nv in ban[v]:if nv < v:seg_to_small.update(comp[A[nv]],idx[nv])if group[v]==target:seg_to_small.update(comp[A[v]],idx[v])for v in Vs[::-1]:for nv in ban[v]:if v < nv:seg_from_large.update(comp[B[nv]],-1)memo_from[v] = max(memo_from[v],seg_from_large.query(0,comp[A[v]]))for nv in ban[v]:if v < nv:seg_from_large.update(comp[B[nv]],idx[nv])if group[v]==target:seg_from_large.update(comp[B[v]],idx[v])for v in Vs:for nv in ban[v]:if nv < v:seg_from_small.update(comp[A[nv]],-1)memo_from[v] = max(memo_from[v],seg_from_small.query(0,comp[B[v]]))for nv in ban[v]:if nv < v:seg_from_small.update(comp[A[nv]],idx[nv])if group[v]==target:seg_from_small.update(comp[A[v]],idx[v])for v in Vs:if memo_to[v]!=N:nv = clique[target][memo_to[v]]res.add((v,nv))memo_to[v] = Nif memo_from[v]!=-1:pv = clique[target][memo_from[v]]res.add((pv,v))memo_from[v] = -1ban[v] = []print(len(res))for u,v in res:print(u+1,v+1)import sysinput = lambda :sys.stdin.buffer.readline()mi = lambda :map(int,input().split())li = lambda :list(mi())N,M = mi()A = li()B = li()E = [tuple(mi()) for i in range(M)]solve(N,A,B,M,E)