結果
問題 | No.1955 Not Prime |
ユーザー |
![]() |
提出日時 | 2024-04-15 12:24:43 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 543 ms / 2,000 ms |
コード長 | 4,457 bytes |
コンパイル時間 | 287 ms |
コンパイル使用メモリ | 82,264 KB |
実行使用メモリ | 118,624 KB |
最終ジャッジ日時 | 2024-10-05 08:23:21 |
合計ジャッジ時間 | 6,511 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 26 |
ソースコード
import sysinput = sys.stdin.readlinefrom math import sqrt, ceildef Sieve(n):lst = [True] * (n + 1)lst[0] = lst[1] = Falsefor i in range(2, ceil(sqrt(n)) + 1):if lst[i]:for j in range(2 * i, n + 1, i):lst[j] = Falsereturn lstclass DirectedGraph():def __init__(self, N):self.N = Nself.G = [[] for i in range(N)]self.rG = [[] for i in range(N)]self.order = []self.used1 = [0] * Nself.used2 = [0] * Nself.group = [-1] * Nself.label = 0self.seen = [0] * Nself.Edge = set()def add_edge(self, u, v):#多重辺は排除するif (u, v) not in self.Edge:self.G[u].append(v)self.rG[v].append(u)self.Edge.add((u, v))def dfs(self, s):stack = [~s, s]while stack:u = stack.pop()if u >= 0:if self.used1[u]:continueself.used1[u] = 1for v in self.G[u]:if self.used1[v]:continuestack.append(~v)stack.append(v)else:u = ~uif self.seen[u]:continueself.seen[u]= 1self.order.append(u)def rdfs(self, s, num):stack = [s]while stack:u = stack.pop()if u >= 0:self.used2[u] = 1self.group[u] = numfor v in self.rG[u]:if self.used2[v]:continuestack.append(v)def scc(self):for i in range(self.N):if self.used1[i]:continueself.dfs(i)for s in reversed(self.order):if self.used2[s]:continueself.rdfs(s, self.label)self.label += 1return self.label, self.groupdef construct(self):nG = [set() for _ in range(self.label)]mem = [[] for i in range(self.label)]for s in range(self.N):now = self.group[s]for u in self.G[s]:if now == self.group[u]:continuenG[now].add(self.group[u])mem[now].append(s)return nG, memclass TwoSAT():def __init__(self, N):self.N = Nself.G = DirectedGraph(2 * N)def add(self, x1, x2, f1, f2):if f1 == True and f2 == True:# ¬x1∪¬x2# (x1⇒¬x2)∩(x2⇒¬x1)self.G.add_edge(x1, x2 + self.N)self.G.add_edge(x2, x1 + self.N)if f1 == True and f2 == False:# ¬x1∪x2# (x1⇒x2)∩(¬x2⇒¬x1)self.G.add_edge(x1, x2)self.G.add_edge(x2 + self.N, x1 + self.N)if f1 == False and f2 == True:# x1∪¬x2# (¬x1⇒¬x2)∩(x2⇒x1)self.G.add_edge(x1 + self.N, x2 + self.N)self.G.add_edge(x2, x1)if f1 == False and f2 == False:# x1∪x2# (¬x1⇒x2)∩(¬x2⇒x1)self.G.add_edge(x1 + self.N, x2)self.G.add_edge(x2 + self.N, x1)def check(self):_, group = self.G.scc()ans = []for i in range(self.N):if group[i] == group[i + self.N]:print("No")exit()if group[i] > group[i + self.N]:ans.append(1)else:ans.append(0)return ansN = int(input())A, B = [], []S = set()for i in range(N):a, b = input().split()if (a, b) in S:continueS.add((a, b))S.add((b, a))A.append(a)B.append(b)N = len(A)D = Sieve(10**6+5)TS = TwoSAT(N)for i in range(N):for j in range(i, N):if D[int(A[i]+B[j])] or D[int(A[j]+B[i])]:TS.add(i, j, True, True)if D[int(B[i]+B[j])] or D[int(A[j]+A[i])]:TS.add(i, j, False, True)if D[int(A[i]+A[j])] or D[int(B[j]+B[i])]:TS.add(i, j, True, False)if D[int(B[i]+A[j])] or D[int(B[j]+A[i])]:TS.add(i, j, False, False)if TS.check():print("Yes")