結果
問題 | No.1665 quotient replace |
ユーザー |
![]() |
提出日時 | 2023-12-02 03:18:19 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,492 ms / 3,000 ms |
コード長 | 19,775 bytes |
コンパイル時間 | 355 ms |
コンパイル使用メモリ | 82,432 KB |
実行使用メモリ | 248,792 KB |
最終ジャッジ日時 | 2024-09-26 16:20:09 |
合計ジャッジ時間 | 26,473 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 41 |
ソースコード
import sysreadline=sys.stdin.readlinefrom collections import defaultdict,Counterclass UnionFind:def __init__(self,N,label=None,f=None,weighted=False,rollback=False):self.N=Nself.parents=[None]*self.Nself.size=[1]*self.Nself.roots={i for i in range(self.N)}self.label=labelif self.label!=None:self.label=[x for x in label]self.f=fself.weighted=weightedif self.weighted:self.weight=[0]*self.Nself.rollback=rollbackif self.rollback:self.operate_list=[]self.operate_set=[]def Find(self,x):stack=[]while self.parents[x]!=None:stack.append(x)x=self.parents[x]if not self.rollback:if self.weighted:w=0for y in stack[::-1]:self.parents[y]=xw+=self.weight[y]self.weight[y]=welse:for y in stack[::-1]:self.parents[y]=xreturn xdef Union(self,x,y,w=None):root_x=self.Find(x)root_y=self.Find(y)if self.rollback:self.operate_list.append([])self.operate_set.append([])if root_x==root_y:if self.weighted:if self.weight[y]-self.weight[x]==w:return Trueelse:return Falseelse:if self.size[root_x]<self.size[root_y]:x,y=y,xroot_x,root_y=root_y,root_xif self.weighted:w=-wif self.rollback:self.operate_list[-1].append((self.parents,root_y,self.parents[root_y]))self.operate_list[-1].append((self.size,root_x,self.size[root_x]))self.operate_set[-1].append(root_y)if self.label!=None:self.operate_list[-1]((self.label,root_x,self.label[root_x]))if self.weighted:self.operate_list[-1].append((self.weight,root_y,self.weight[root_y]))self.parents[root_y]=root_xself.size[root_x]+=self.size[root_y]self.roots.remove(root_y)if self.label!=None:self.label[root_x]=self.f(self.label[root_x],self.label[root_y])if self.weighted:self.weight[root_y]=w+self.weight[x]-self.weight[y]def Size(self,x):return self.size[self.Find(x)]def Same(self,x,y):return self.Find(x)==self.Find(y)def Label(self,x):return self.label[self.Find(x)]def Weight(self,x,y):root_x=self.Find(x)root_y=self.Find(y)if root_x!=root_y:return Nonereturn self.weight[y]-self.weight[x]def Roots(self):return list(self.roots)def Linked_Components_Count(self):return len(self.roots)def Linked_Components(self):linked_components=defaultdict(list)for x in range(self.N):linked_components[self.Find(x)].append(x)return linked_componentsdef Rollback(self):assert self.rollbackif self.operate_list:for lst,x,v in self.operate_list.pop():lst[x]=vfor x in self.operate_set.pop():self.roots.add(x)return Trueelse:return Falsedef __str__(self):linked_components=defaultdict(list)for x in range(self.N):linked_components[self.Find(x)].append(x)return "\n".join(f"{r}: {linked_components[r]}" for r in sorted(list(linked_components.keys())))class Graph:def __init__(self,V,edges=None,graph=None,directed=False,weighted=False,inf=float("inf")):self.V=Vself.directed=directedself.weighted=weightedself.inf=infif graph!=None:self.graph=graph"""self.edges=[]for i in range(self.V):if self.weighted:for j,d in self.graph[i]:if self.directed or not self.directed and i<=j:self.edges.append((i,j,d))else:for j in self.graph[i]:if self.directed or not self.directed and i<=j:self.edges.append((i,j))"""else:self.edges=edgesself.graph=[[] for i in range(self.V)]if weighted:for i,j,d in self.edges:self.graph[i].append((j,d))if not self.directed:self.graph[j].append((i,d))else:for i,j in self.edges:self.graph[i].append(j)if not self.directed:self.graph[j].append(i)def Warshall_Floyd(self,route_restoration=False):dist=[[self.inf]*self.V for i in range(self.V)]for i in range(self.V):dist[i][i]=0if route_restoration:parents=[[j for j in range(self.V)] for i in range(self.V)]for i,j,d in self.edges:if i==j:continueif dist[i][j]>d:dist[i][j]=dif route_restoration:parents[i][j]=iif not self.directed and dist[j][i]>d:dist[j][i]=dif route_restoration:parents[j][i]=jfor k in range(self.V):for i in range(self.V):for j in range(self.V):if dist[i][j]>dist[i][k]+dist[k][j]:dist[i][j]=dist[i][k]+dist[k][j]if route_restoration:parents[i][j]=parents[k][j]for i in range(self.V):if dist[i][i]<0:for j in range(self.V):if dist[i][j]!=self.inf:dist[i][j]=-self.infif route_restoration:for i in range(self.V):if dist[i][i]==0:parents[i][i]=Nonereturn dist,parentselse:return distdef Kruskal(self,maximize=False,spanning_tree=False):UF=UnionFind(self.V)sorted_edges=sorted(self.edges if self.weighted else [(x,y,1) for x,y in self.edges],key=lambda tpl:tpl[2],reverse=maximize)if spanning_tree:st=[]else:cost=0for x,y,d in sorted_edges:if not UF.Same(x,y):UF.Union(x,y)if spanning_tree:st.append((x,y,d))else:cost+=dreturn st if spanning_tree else costdef Inversion_Number(lst,weight=False,weakly=False):compress,decompress=Compress(lst)compressed_lst=[compress[x] for x in lst]N=len(compress)if not weight:weight=[1]*len(lst)ST=Segment_Tree(N,lambda x,y:x+y,0)inversion_number=0for c,x in zip(weight,compressed_lst):inversion_number+=ST.Fold(x if weakly else x+1,N)*cST[x]+=creturn inversion_numberdef Compress(lst):decomp=sorted(list(set(lst)))comp={x:i for i,x in enumerate(decomp)}return comp,decompclass Segment_Tree:def __init__(self,N,f,e,lst=None,dynamic=False):self.f=fself.e=eself.N=Nif dynamic:self.segment_tree=defaultdict(lambda:self.e)else:if lst==None:self.segment_tree=[self.e]*2*self.Nelse:assert len(lst)<=self.Nself.segment_tree=[self.e]*self.N+[x for x in lst]+[self.e]*(N-len(lst))for i in range(self.N-1,0,-1):self.segment_tree[i]=self.f(self.segment_tree[i<<1],self.segment_tree[i<<1|1])def __getitem__(self,i):if type(i)==int:if -self.N<=i<0:return self.segment_tree[i+self.N*2]elif 0<=i<self.N:return self.segment_tree[i+self.N]else:raise IndexError("list index out of range")else:a,b,c=i.start,i.stop,i.stepif a==None:a=self.Nelse:a+=self.Nif b==None:b=self.N*2else:b+=self.Nreturn self.segment_tree[slice(a,b,c)]def __setitem__(self,i,x):if -self.N<=i<0:i+=self.N*2elif 0<=i<self.N:i+=self.Nelse:raise IndexError("list index out of range")self.segment_tree[i]=xwhile i>1:i>>= 1self.segment_tree[i]=self.f(self.segment_tree[i<<1],self.segment_tree[i<<1|1])def Build(self,lst):for i,x in enumerate(lst,self.N):self.segment_tree[i]=xfor i in range(self.N-1,0,-1):self.segment_tree[i]=self.f(self.segment_tree[i<<1],self.segment_tree[i<<1|1])def Fold(self,L=None,R=None):if L==None:L=self.Nelse:L+=self.Nif R==None:R=self.N*2else:R+=self.NvL=self.evR=self.ewhile L<R:if L&1:vL=self.f(vL,self.segment_tree[L])L+=1if R&1:R-=1vR=self.f(self.segment_tree[R],vR)L>>=1R>>=1return self.f(vL,vR)def Fold_Index(self,L=None,R=None):if L==None:L=self.Nelse:L+=self.Nif R==None:R=self.N*2else:R+=self.Nif L==R:return Nonex=self.Fold(L-self.N,R-self.N)while L<R:if L&1:if self.segment_tree[L]==x:i=LbreakL+=1if R&1:R-=1if self.segment_tree[R]==x:i=RbreakL>>=1R>>=1while i<self.N:if self.segment_tree[i]==self.segment_tree[i<<1]:i<<=1else:i<<=1i|=1i-=self.Nreturn idef Bisect_Right(self,L=None,f=None):if L==self.N:return self.Nif L==None:L=0L+=self.Nvl=self.evr=self.el,r=L,self.N*2while l<r:if l&1:vl=self.f(vl,self.segment_tree[l])l+=1if r&1:r-=1vr=self.f(self.segment_tree[r],vr)l>>=1r>>=1if f(self.f(vl,vr)):return self.Nv=self.ewhile True:while L%2==0:L>>=1vv=self.f(v,self.segment_tree[L])if f(vv):v=vvL+=1else:while L<self.N:L<<=1vv=self.f(v,self.segment_tree[L])if f(vv):v=vvL+=1return L-self.Ndef Bisect_Left(self,R=None,f=None):if R==0:return 0if R==None:R=self.NR+=self.Nvl=self.evr=self.el,r=self.N,Rwhile l<r:if l&1:vl=self.f(vl,self.segment_tree[l])l+=1if r&1:r-=1vr=self.f(self.segment_tree[r],vr)l>>=1r>>=1if f(self.f(vl,vr)):return 0v=self.ewhile True:R-=1while R>1 and R%2:R>>=1vv=self.f(self.segment_tree[R],v)if f(vv):v=vvelse:while R<self.N:R=2*R+1vv=self.f(self.segment_tree[R],v)if f(vv):v=vvR-=1return R+1-self.Ndef __str__(self):return "["+", ".join(map(str,self.segment_tree[self.N:]))+"]"class Cumsum:def __init__(self,lst,mod=0):self.N=len(lst)self.mod=modself.cumsum=[0]*(self.N+1)self.cumsum[0]=0for i in range(1,self.N+1):self.cumsum[i]=self.cumsum[i-1]+lst[i-1]if self.mod:self.cumsum[i]%=self.moddef __getitem__(self,i):if type(i)==int:if 0<=i<self.N:a,b=i,i+1elif -self.N<=i<0:a,b=i+self.N,i+self.N+1else:raise IndexError('list index out of range')else:a,b=i.start,i.stopif a==None or a<-self.N:a=0elif self.N<=a:a=self.Nelif a<0:a+=self.Nif b==None or self.N<=b:b=self.Nelif b<-self.N:b=0elif b<0:b+=self.Ns=self.cumsum[b]-self.cumsum[a]if self.mod:s%=self.modreturn sdef __setitem__(self,i,x):if -self.N<=i<0:i+=self.Nelif not 0<=i<self.N:raise IndexError('list index out of range')self.cumsum[i+1]=self.cumsum[i]+xif self.mod:self.cumsum[i+1]%=self.moddef __len__(self):return self.Ndef __str__(self):lst=[self.cumsum[i+1]-self.cumsum[i] for i in range(self.N)]if self.mod:for i in range(self.N):lst[i]%=self.modreturn "["+", ".join(map(str,lst))+"]"def Swap_Count(N,A,B):if sorted(A)==sorted(B):idxA={tpl:i for i,tpl in enumerate(sorted([(A[i],i) for i in range(N)]))}idxB={tpl:i for i,tpl in enumerate(sorted([(B[i],i) for i in range(N)]))}for i in range(N):A[i]=idxA[(A[i],i)]B[i]=idxB[(B[i],i)]idx={A[i]:i for i in range(N)}for i in range(N):B[i]=idx[B[i]]retu=Inversion_Number(B)else:retu=-1return retudef Extended_Euclid(n,m):stack=[]while m:stack.append((n,m))n,m=m,n%mif n>=0:x,y=1,0else:x,y=-1,0for i in range(len(stack)-1,-1,-1):n,m=stack[i]x,y=y,x-(n//m)*yreturn x,yclass MOD:def __init__(self,p,e=None):self.p=pself.e=eif self.e==None:self.mod=self.pelse:self.mod=self.p**self.edef Pow(self,a,n):a%=self.modif n>=0:return pow(a,n,self.mod)else:#assert math.gcd(a,self.mod)==1x=Extended_Euclid(a,self.mod)[0]return pow(x,-n,self.mod)def Build_Fact(self,N):assert N>=0self.factorial=[1]if self.e==None:for i in range(1,N+1):self.factorial.append(self.factorial[-1]*i%self.mod)else:self.cnt=[0]*(N+1)for i in range(1,N+1):self.cnt[i]=self.cnt[i-1]ii=iwhile ii%self.p==0:ii//=self.pself.cnt[i]+=1self.factorial.append(self.factorial[-1]*ii%self.mod)self.factorial_inve=[None]*(N+1)self.factorial_inve[-1]=self.Pow(self.factorial[-1],-1)for i in range(N-1,-1,-1):ii=i+1while ii%self.p==0:ii//=self.pself.factorial_inve[i]=(self.factorial_inve[i+1]*ii)%self.moddef Build_Inverse(self,N):self.inverse=[None]*(N+1)assert self.p>Nself.inverse[1]=1for n in range(2,N+1):if n%self.p==0:continuea,b=divmod(self.mod,n)self.inverse[n]=(-a*self.inverse[b])%self.moddef Inverse(self,n):return self.inverse[n]def Fact(self,N):if N<0:return 0retu=self.factorial[N]if self.e!=None and self.cnt[N]:retu*=pow(self.p,self.cnt[N],self.mod)%self.modretu%=self.modreturn retudef Fact_Inve(self,N):if self.e!=None and self.cnt[N]:return Nonereturn self.factorial_inve[N]def Comb(self,N,K,divisible_count=False):if K<0 or K>N:return 0retu=self.factorial[N]*self.factorial_inve[K]%self.mod*self.factorial_inve[N-K]%self.modif self.e!=None:cnt=self.cnt[N]-self.cnt[N-K]-self.cnt[K]if divisible_count:return retu,cntelse:retu*=pow(self.p,cnt,self.mod)retu%=self.modreturn retuclass Prime:def __init__(self,N):assert N<=10**8self.smallest_prime_factor=[None]*(N+1)for i in range(2,N+1,2):self.smallest_prime_factor[i]=2n=int(N**.5)+1for p in range(3,n,2):if self.smallest_prime_factor[p]==None:self.smallest_prime_factor[p]=pfor i in range(p**2,N+1,2*p):if self.smallest_prime_factor[i]==None:self.smallest_prime_factor[i]=pfor p in range(n,N+1):if self.smallest_prime_factor[p]==None:self.smallest_prime_factor[p]=pself.primes=[p for p in range(N+1) if p==self.smallest_prime_factor[p]]def Factorize(self,N):assert N>=1factors=defaultdict(int)if N<=len(self.smallest_prime_factor)-1:while N!=1:factors[self.smallest_prime_factor[N]]+=1N//=self.smallest_prime_factor[N]else:for p in self.primes:while N%p==0:N//=pfactors[p]+=1if N<p*p:if N!=1:factors[N]+=1breakif N<=len(self.smallest_prime_factor)-1:while N!=1:factors[self.smallest_prime_factor[N]]+=1N//=self.smallest_prime_factor[N]breakelse:if N!=1:factors[N]+=1return factorsdef Divisors(self,N):assert N>0divisors=[1]for p,e in self.Factorize(N).items():pow_p=[1]for _ in range(e):pow_p.append(pow_p[-1]*p)divisors=[i*j for i in divisors for j in pow_p]return divisorsdef Is_Prime(self,N):return N==self.smallest_prime_factor[N]def Totient(self,N):for p in self.Factorize(N).keys():N*=p-1N//=preturn Ndef Mebius(self,N):fact=self.Factorize(N)for e in fact.values():if e>=2:return 0else:if len(fact)%2==0:return 1else:return -1N=int(input())A=list(map(int,readline().split()))max_A=max(A)Pr=Prime(max_A)grundy=0for a in A:grundy^=sum(Pr.Factorize(a).values())if grundy:ans="white"else:ans="black"print(ans)