class Binary_Trie: """ Reference https://judge.yosupo.jp/submission/35057 https://judge.yosupo.jp/submission/53782 """ def __init__(self, max_value, allow_multiple=False, query_number=None): self.bit=max_value.bit_length() self.upper=1<>i)&1 if self.arc[2*v+d]==-1: if self.query_number!=None: self.id+=1 self.arc[2*v+d]=self.id else: self.arc[2*v+d]=len(self.size) self.arc.append(-1); self.arc.append(-1) self.terminal.append(0) self.size.append(0) v=self.arc[2*v+d] self.v_list[i]=v if self.multi or self.terminal[v]==0: self.terminal[v]+=1 for w in self.v_list: self.size[w]+=1 def discard(self, x): """ x が存在する場合, x を削除する. """ if not (0<=x>i)&1 if self.arc[2*v+d]==-1: return v=self.arc[2*v+d] self.v_list[i]=v if self.terminal[v]>0: self.terminal[v]-=1 for w in self.v_list: self.size[w]-=1 def erase(self, x, k): """ x を高々 k 回削除する (ただし, k=-1 のときは無限回)""" assert -1<=k if not (0<=x>i)&1 if self.arc[2*v+d]==-1: return v=self.arc[2*v+d] self.v_list[i]=v if (k==-1) or (self.terminal[v]0: self.terminal[v]-=k for w in self.v_list: self.size[w]-=k def count(self, x): """ x の個数を求める. """ if not (0<=x>i)&1 if self.arc[2*v+d]==-1: return 0 v=self.arc[2*v+d] return self.terminal[v] def __contains__(self, x): return bool(self.count(x)) def __len__(self): return self.size[0] def __bool__(self): return bool(len(self)) def less_count(self, x, equal=False): """ x 未満の要素数を求める (equal=True のときは, "未満" が "以下" になる)""" x^=self.lazy_xor if equal: x+=1 if x<0: return 0 if self.upper<=x: return len(self) v=0 res=0 for i in reversed(range(self.bit)): d=(x>>i)&1 lc=self.arc[2*v] rc=self.arc[2*v+1] if (self.lazy_xor>>i)&1: lc,rc=rc,lc if d: if lc!=-1: res+=self.size[lc] if rc==-1: return res v=rc else: if lc==-1: return res v=lc return res def more_count(self, x, equal=False): """ x より大きい要素数を求める (equal=True のときは, "より大きい" が "以上" になる)""" return len(self)-self.less_count(x,not equal) def low_value(self, x, equal=False, default=None): """ x 未満の整数のうち, 最大の整数を求める (存在しない場合は default). equal: True のとき, "未満" が "以下" になる. """ x^=self.lazy_xor if equal: x+=1 alpha=self.less_count(x,False) if alpha==0: return default else: return self.kth_element(alpha,1) def high_value(self, x, equal=False, default=None): """ x より大きい整数のうち, 最小の整数を求める (存在しない場合は default) equal: True のとき, "より大きい" が "以上" になる. """ x^=self.lazy_xor if equal: x-=1 beta=self.more_count(x,False) if beta==0: return default else: return self.kth_element(-beta,0) def kth_element(self, k, index=0, default=-1): """ index -indexed で k 番目に小さい値を求める. ただし, index=0, k<0 のときは |k| 番目に大きい値になる. """ if k<0: k+=self.size[0] k-=index if not (0<=k>i)&1: lc,rc=rc,lc if lc==-1: v=rc res|=1<>k)&1 def calc(C,D): T=[defaultdict(list) for _ in range(K+1)] N=len(C) for S in range(1<L: for w in G1[r][F1[r][-1]]: T[r].discard(w) F1[r].pop() if k+r<=K: for value in G0[k][cost]: X+=T[r].more_count(max(0, P-value), True) return X #================================================== print(solve())