結果
問題 | No.1698 Face to Face |
ユーザー |
![]() |
提出日時 | 2021-09-18 16:32:24 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 4,120 ms / 5,000 ms |
コード長 | 4,390 bytes |
コンパイル時間 | 166 ms |
コンパイル使用メモリ | 82,376 KB |
実行使用メモリ | 143,752 KB |
最終ジャッジ日時 | 2024-07-19 10:12:40 |
合計ジャッジ時間 | 88,585 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 45 |
ソースコード
class UnionFind_AB:def __init__(self, N):self.p = [-1] * Nself.L = [i for i in range(N)]self.R = [i for i in range(N)]def reset(self):for i in range(len(self.p)):self.p[i] = -1self.L[i] = iself.R[i] = idef root(self, x):while self.p[x] >= 0:x = self.p[x]return xdef same(self, x, y):return self.root(x) == self.root(y)def unite(self, x, y):x = self.root(x)y = self.root(y)if x == y:returnp = self.pif p[x] > p[y]:p[y] += p[x]p[x] = yself.L[y] = min(self.L[y],self.L[x])self.R[y] = max(self.R[y],self.R[x])else:p[x] += p[y]p[y] = xself.L[x] = min(self.L[y],self.L[x])self.R[x] = max(self.R[y],self.R[x])def size(self, x):return -self.p[self.root(x)]def left(self, v):return self.L[self.root(v)]def right(self,v):return self.R[self.root(v)]class UnionFind_IDX:def __init__(self, N):self.p = [-1] * Nself.num_pair = [0] * Nself.score = 0def root(self, x):while self.p[x] >= 0:x = self.p[x]return xdef same(self, x, y):return self.root(x) == self.root(y)def unite(self, x, y):x = self.root(x)y = self.root(y)if x == y:returnself.score -= self.sub_score(x) + self.sub_score(y)p = self.pif p[x] > p[y]:p[y] += p[x]p[x] = yself.num_pair[y] += self.num_pair[x]self.score += self.sub_score(y)else:p[x] += p[y]p[y] = xself.num_pair[x] += self.num_pair[y]self.score += self.sub_score(x)def add_pair(self,v):self.score -= self.sub_score(self.root(v))self.num_pair[self.root(v)]+=1self.score += self.sub_score(self.root(v))def size(self, x):return -self.p[self.root(x)]def sub_score(self,v):return min(-self.p[self.root(v)],self.num_pair[self.root(v)])import sysfrom typing import Unioninput = sys.stdin.readlinedef main():n = int(input())a = list(map(int,input().split()))b = list(map(int,input().split()))z = list(map(int,input().split()))ida = [-1]*nidb = [-1]*nfor i in range(n):a[i]-=1b[i]-=1z[i]-=1ida[a[i]]=iidb[b[i]]=ipos_left = [-1]*nl = [-1]*nr = [n]*nmid = [[]for i in range(n)]ufa = UnionFind_AB(n)ufb = UnionFind_AB(n)for q in range(17):for i in range(n):if r[i]-l[i]>1:mid[(l[i]+r[i])//2].append(i)if q > 0:ufa.reset()ufb.reset()for k in range(n):ia = ida[k]ib = idb[k]if 0<ia and a[ia-1]<=k:ufa.unite(ia-1,ia)if ia+1<n and a[ia+1]<=k:ufa.unite(ia,ia+1)if 0<ib and b[ib-1]<=k:ufb.unite(ib-1,ib)if ib+1<n and b[ib+1]<=k:ufb.unite(ib,ib+1)for j in mid[k]:la, ra = ufa.left(ida[j]),ufa.right(ida[j])lb, rb = ufb.left(idb[z[j]]),ufb.right(idb[z[j]])if ra < lb or rb < la:l[j] = kelse:r[j] = kpos_left[j] = max(la,lb)mid[k].clear()for i in range(n):mid[r[i]].append(i)less_k = [0]*nufi = UnionFind_IDX(n)ans = []for k in range(n):ia, ib = ida[k],idb[k]less_k[ia]+=1less_k[ib]+=1if less_k[ia]==2:if 0<ia and less_k[ia-1]==2:ufi.unite(ia-1,ia)if ia+1<n and less_k[ia+1]==2:ufi.unite(ia,ia+1)if less_k[ib]==2:if 0<ib and less_k[ib-1]==2:ufi.unite(ib-1,ib)if ib+1<n and less_k[ib+1]==2:ufi.unite(ib,ib+1)for x in mid[k]:ufi.add_pair(pos_left[x])ans.append(ufi.score)print("\n".join(map(str,ans)))if __name__=='__main__':main()