結果
問題 | No.1698 Face to Face |
ユーザー |
![]() |
提出日時 | 2021-09-18 17:04:45 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 3,992 ms / 5,000 ms |
コード長 | 4,278 bytes |
コンパイル時間 | 188 ms |
コンパイル使用メモリ | 82,432 KB |
実行使用メモリ | 217,296 KB |
最終ジャッジ日時 | 2024-07-19 10:06:55 |
合計ジャッジ時間 | 87,728 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
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 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] = yif self.L[y] > self.L[x]:self.L[y] = self.L[x]if self.R[y] < self.R[x]:self.R[y] = self.R[x]else:p[x] += p[y]p[y] = xif self.L[x] > self.L[y]:self.L[x] = self.L[y]if self.R[x] < self.R[y]:self.R[x] = self.R[y]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):rv = self.root(v)self.score -= self.sub_score(rv)self.num_pair[rv]+=1self.score += self.sub_score(rv)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 collections import dequedef main():input = sys.stdin.readlinen = int(input())a = list(map(int,input().split()))b = list(map(int,input().split()))z = list(map(int,input().split()))ida = [-1]*nidb = [-1]*nrn = range(n)for i in rn:a[i]-=1b[i]-=1z[i]-=1ida[a[i]]=iidb[b[i]]=ipos_left = [-1]*nl = [-1]*nr = [n]*nmid = [[] for i in rn]for _ in [0]*(17):for i in rn:if r[i]-l[i]>1:mid[(l[i]+r[i])//2].append(i)ufa = UnionFind_AB(n)ufb = UnionFind_AB(n)for k in rn: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 rn:mid[r[i]].append(i)less_k = [0]*nufi = UnionFind_IDX(n)ans = []for k in rn: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 j in mid[k]:ufi.add_pair(pos_left[j])ans.append(ufi.score)print("\n".join(map(str,ans)))if __name__=='__main__':main()