結果
問題 | No.2020 Sum of Common Prefix Length |
ユーザー |
![]() |
提出日時 | 2023-08-11 05:16:25 |
言語 | PyPy3 (7.3.15) |
結果 |
RE
|
実行時間 | - |
コード長 | 14,079 bytes |
コンパイル時間 | 527 ms |
コンパイル使用メモリ | 82,304 KB |
実行使用メモリ | 360,992 KB |
最終ジャッジ日時 | 2024-11-17 18:46:38 |
合計ジャッジ時間 | 23,944 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 2 RE * 36 |
ソースコード
import sysreadline=sys.stdin.readlineclass Node:def __init__(self,parent,e,i):self.parent=parentself.children={}self.value=eself.cnt=0self.i=idef Parent(self):return self.parentdef __getitem__(self,x):return self.children[x]class Trie:def __init__(self,e=None):self.e=eself.root=Node(None,self.e,0)self.node_cnt=1def __getitem__(self,key):node=self.rootfor x in key:if not x in node.children:return self.enode=node[x]return node.valuedef __setitem__(self,key,value):node=self.rootfor x in key:if not x in node.children:node.children[x]=Node(node,self.e,self.node_cnt)self.node_cnt+=1node=node[x]if node.value==self.e:node=self.rootnode.cnt+=1for x in key:node=node[x]node.cnt+=1node.value=valuedef __delitem__(self,key):node=self.rootfor x in key:if not x in node.children:returnnode=node[x]node=self.rootnode.cnt-=1for x in key:node=node[x]node.cnt-=1node.value=self.edef __contains__(self,key):node=self.rootfor x in key:if not x in node.children:return Falsenode=node[x]return Truedef __len__(self):return self.root.cntdef Nodes(self):queue=[self.root]retu=[]while queue:node=queue.pop()retu.append(node)for x,node in node.children.items():queue.append(node)return retuclass 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=graphself.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 SIV_DFS(self,s,bipartite_graph=False,cycle_detection=False,directed_acyclic=False,euler_tour=False,linked_components=False,lowlink=False,parents=False,postorder=False,preorder=False,subtree_size=False,topological_sort=False,unweighted_dist=False,weighted_dist=False):seen=[False]*self.Vfinished=[False]*self.Vif directed_acyclic or cycle_detection or topological_sort:dag=Trueif euler_tour:et=[]if linked_components:lc=[]if lowlink:order=[None]*self.Vll=[None]*self.Vidx=0if parents or cycle_detection or lowlink or subtree_size:ps=[None]*self.Vif postorder or topological_sort:post=[]if preorder:pre=[]if subtree_size:ss=[1]*self.Vif unweighted_dist or bipartite_graph:uwd=[self.inf]*self.Vuwd[s]=0if weighted_dist:wd=[self.inf]*self.Vwd[s]=0stack=[(s,0)] if self.weighted else [s]while stack:if self.weighted:x,d=stack.pop()else:x=stack.pop()if not seen[x]:seen[x]=Truestack.append((x,d) if self.weighted else x)if euler_tour:et.append(x)if linked_components:lc.append(x)if lowlink:order[x]=idxll[x]=idxidx+=1if preorder:pre.append(x)for y in self.graph[x]:if self.weighted:y,d=yif not seen[y]:stack.append((y,d) if self.weighted else y)if parents or cycle_detection or lowlink or subtree_size:ps[y]=xif unweighted_dist or bipartite_graph:uwd[y]=uwd[x]+1if weighted_dist:wd[y]=wd[x]+delif not finished[y]:if (directed_acyclic or cycle_detection or topological_sort) and dag:dag=Falseif cycle_detection:cd=(y,x)elif not finished[x]:finished[x]=Trueif euler_tour:et.append(~x)if lowlink:bl=Truefor y in self.graph[x]:if self.weighted:y,d=yif ps[x]==y and bl:bl=Falsecontinuell[x]=min(ll[x],order[y])if x!=s:ll[ps[x]]=min(ll[ps[x]],ll[x])if postorder or topological_sort:post.append(x)if subtree_size:for y in self.graph[x]:if self.weighted:y,d=yif y==ps[x]:continuess[x]+=ss[y]if bipartite_graph:bg=[[],[]]for tpl in self.edges:x,y=tpl[:2] if self.weighted else tplif uwd[x]==self.inf or uwd[y]==self.inf:continueif not uwd[x]%2^uwd[y]%2:bg=Falsebreakelse:for x in range(self.V):if uwd[x]==self.inf:continuebg[uwd[x]%2].append(x)retu=()if bipartite_graph:retu+=(bg,)if cycle_detection:if dag:cd=[]else:y,x=cdcd=self.Route_Restoration(y,x,ps)retu+=(cd,)if directed_acyclic:retu+=(dag,)if euler_tour:retu+=(et,)if linked_components:retu+=(lc,)if lowlink:retu=(ll,)if parents:retu+=(ps,)if postorder:retu+=(post,)if preorder:retu+=(pre,)if subtree_size:retu+=(ss,)if topological_sort:if dag:tp_sort=post[::-1]else:tp_sort=[]retu+=(tp_sort,)if unweighted_dist:retu+=(uwd,)if weighted_dist:retu+=(wd,)if len(retu)==1:retu=retu[0]return retuclass 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:]))+"]"N=int(readline())S=[readline().rstrip() for n in range(N)]SS=[list(s) for s in S]Q=int(readline())query=[]for q in range(Q):lst=readline().split()if lst[0]=="1":_,x,c=lstx=int(x)-1SS[x]+=["c"]query.append((1,x,c))else:_,x=lstx=int(x)-1query.append((2,x))Tr=Trie(0)for s in SS:Tr[s]=0nodes=Tr.Nodes()edges=[]le=len(nodes)for n0 in nodes:for x,n1 in n0.children.items():edges.append((n0.i,n1.i))G=Graph(le,edges=edges)tour=G.SIV_DFS(0,euler_tour=True)idx_in=[None]*leidx_out=[None]*lefor i in range(2*le):if tour[i]>=0:idx_in[tour[i]]=ielse:idx_out[~tour[i]]=iST=Segment_Tree(2*le,lambda x,y:x+y,0)node=[Tr.root]*Nfor i in range(N):for s in S[i]:node[i]=node[i].children[s]ST[idx_in[node[i].i]]+=1ST[idx_out[node[i].i]]-=1for tpl in query:if tpl[0]==1:_,x,c=tplnode[x]=node[x][c]i=node[x].iST[idx_in[i]]+=1ST[idx_out[i]]-=1else:_,x=tpli=node[x].ians=ST.Fold(0,idx_in[i]+1)print(ans)