結果
問題 | No.1914 Directed by Two Sequences |
ユーザー |
|
提出日時 | 2021-11-05 20:14:43 |
言語 | PyPy3 (7.3.15) |
結果 |
WA
|
実行時間 | - |
コード長 | 10,299 bytes |
コンパイル時間 | 167 ms |
コンパイル使用メモリ | 82,304 KB |
実行使用メモリ | 171,672 KB |
最終ジャッジ日時 | 2024-12-16 01:35:34 |
合計ジャッジ時間 | 52,745 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | WA * 2 |
other | AC * 1 WA * 37 |
ソースコード
"""想定WA"""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 resclass _csr:def __init__(self, n, edges):self.start = [0] * (n + 1)self.elist = [0] * len(edges)for v, _ in edges:self.start[v + 1] += 1for i in range(1, n + 1):self.start[i] += self.start[i - 1]counter = self.start.copy()for v, e in edges:self.elist[counter[v]] = ecounter[v] += 1class scc_graph:"""It calculates the strongly connected components of directed graphs."""def __init__(self, n):"""It creates a directed graph with n vertices and 0 edges.Constraints-----------> 0 <= n <= 10 ** 8Complexity----------> O(n)"""self.n = nself.edges = []def add_edge(self, from_, to):"""It adds a directed edge from the vertex `from_` to the vertex `to`.Constraints-----------> 0 <= from_ < n> 0 <= to < nComplexity----------> O(1) amortized"""# assert 0 <= from_ < self.n# assert 0 <= to < self.nself.edges.append((from_, to))def _scc_ids(self):g = _csr(self.n, self.edges)now_ord = 0group_num = 0visited = []low = [0] * self.norder = [-1] * self.nids = [0] * self.nparent = [-1] * self.nstack = []for i in range(self.n):if order[i] == -1:stack.append(i)stack.append(i)while stack:v = stack.pop()if order[v] == -1:low[v] = order[v] = now_ordnow_ord += 1visited.append(v)for i in range(g.start[v], g.start[v + 1]):to = g.elist[i]if order[to] == -1:stack.append(to)stack.append(to)parent[to] = velse:low[v] = min(low[v], order[to])else:if low[v] == order[v]:while True:u = visited.pop()order[u] = self.nids[u] = group_numif u == v:breakgroup_num += 1if parent[v] != -1:low[parent[v]] = min(low[parent[v]], low[v])for i, x in enumerate(ids):ids[i] = group_num - 1 - xreturn group_num, idsdef scc(self):"""It returns the list of the "list of the vertices" that satisfies the following.> Each vertex is in exactly one "list of the vertices".> Each "list of the vertices" corresponds to the vertex set of a strongly connected component.The order of the vertices in the list is undefined.> The list of "list of the vertices" are sorted in topological order,i.e., for two vertices u, v in different strongly connected components,if there is a directed path from u to v,the list contains u appears earlier than the list contains v.Complexity----------> O(n + m), where m is the number of added edges."""group_num, ids = self._scc_ids()groups = [[] for _ in range(group_num)]for i, x in enumerate(ids):groups[x].append(i)return groupsdef popcount(x):'''xの立っているビット数をカウントする関数(xは64bit整数)'''# 2bitごとの組に分け、立っているビット数を2bitで表現するx = x - ((x >> 1) & 0x5555555555555555)# 4bit整数に 上位2bit + 下位2bit を計算した値を入れるx = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f # 8bitごとx = x + (x >> 8) # 16bitごとx = x + (x >> 16) # 32bitごとx = x + (x >> 32) # 64bitごと = 全部の合計return x & 0x0000007fpopcnt = [popcount(i) for i in range(2**20)]def solve(N,A,B,M,E):A = [a-1 for a in A]B = [b-1 for b in B]G = scc_graph(N)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 hamilton_path(V):n = len(V)if n <= 1:return VA = hamilton_path(V[:n//2])B = hamilton_path(V[n//2:])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):clique[g] = hamilton_path(clique[g])for i in range(len(clique[g])):idx[clique[g][i]] = ifor u,v in zip(clique[g],clique[g][1:]):G.add_edge(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 = []seg_to_large = SegmentTree([N]*2*N,min,N)seg_to_small = SegmentTree([N]*2*N,min,N)seg_from_large = SegmentTree([-1]*2*N,max,-1)seg_from_small = SegmentTree([-1]*2*N,max,-1)for i in range(n):target = ci[i]Vs += clique[target]Vs.sort()for nv in clique[target]:for v in edge[nv]:if idx_on_ci[group[v]] <= i:ban[v].append(nv)for v in Vs[::-1]:for nv in ban[v]:if v < nv:seg_to_large.update(B[nv],N)memo_to[v] = min(memo_to[v],seg_to_large.query(A[v],2*N))for nv in ban[v]:if v < nv:seg_to_large.update(B[nv],idx[nv])if group[v]==target:seg_to_large.update(B[v],idx[v])for v in Vs:for nv in ban[v]:if nv < v:seg_to_small.update(A[nv],N)memo_to[v] = min(memo_to[v],seg_to_small.query(B[v],2*N))for nv in ban[v]:if nv < v:seg_to_small.update(A[nv],idx[nv])if group[v]==target:seg_to_small.update(A[v],idx[v])for v in Vs[::-1]:for nv in ban[v]:if v < nv:seg_from_large.update(B[nv],-1)memo_from[v] = max(memo_from[v],seg_from_large.query(0,A[v]))for nv in ban[v]:if v < nv:seg_from_large.update(B[nv],idx[nv])if group[v]==target:seg_from_large.update(B[v],idx[v])for v in Vs:for nv in ban[v]:if nv < v:seg_from_small.update(A[nv],-1)memo_from[v] = max(memo_from[v],seg_from_small.query(0,B[v]))for nv in ban[v]:if nv < v:seg_from_small.update(A[nv],idx[nv])if group[v]==target:seg_from_small.update(A[v],idx[v])for v in Vs:if memo_to[v]!=N:nv = clique[target][memo_to[v]]G.add_edge(v,nv)memo_to[v] = Nif memo_from[v]!=-1:pv = clique[target][memo_from[v]]G.add_edge(pv,v)memo_from[v] = -1ban[v] = []if group[v]==target:seg_to_large.update(B[v],N)seg_to_small.update(A[v],N)seg_from_large.update(B[v],-1)seg_from_small.update(A[v],-1)group_num,ids = G._scc_ids()res = [(i+1,i+2) for i in range(N-1)] + [(N,1)]print(len(res))for u,v in res:print(u,v)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)