結果
問題 | No.2161 Black Market |
ユーザー | 👑 Kazun |
提出日時 | 2022-12-12 18:37:04 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,479 ms / 7,000 ms |
コード長 | 8,510 bytes |
コンパイル時間 | 376 ms |
コンパイル使用メモリ | 81,792 KB |
実行使用メモリ | 260,744 KB |
最終ジャッジ日時 | 2024-11-06 17:16:09 |
合計ジャッジ時間 | 12,339 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 44 ms
55,680 KB |
testcase_01 | AC | 44 ms
55,296 KB |
testcase_02 | AC | 89 ms
76,800 KB |
testcase_03 | AC | 44 ms
55,168 KB |
testcase_04 | AC | 43 ms
55,296 KB |
testcase_05 | AC | 48 ms
55,680 KB |
testcase_06 | AC | 96 ms
76,820 KB |
testcase_07 | AC | 96 ms
77,056 KB |
testcase_08 | AC | 126 ms
77,944 KB |
testcase_09 | AC | 115 ms
76,784 KB |
testcase_10 | AC | 129 ms
78,080 KB |
testcase_11 | AC | 99 ms
77,568 KB |
testcase_12 | AC | 82 ms
77,312 KB |
testcase_13 | AC | 60 ms
65,920 KB |
testcase_14 | AC | 69 ms
68,736 KB |
testcase_15 | AC | 115 ms
78,040 KB |
testcase_16 | AC | 60 ms
67,200 KB |
testcase_17 | AC | 43 ms
55,168 KB |
testcase_18 | AC | 44 ms
55,168 KB |
testcase_19 | AC | 55 ms
64,384 KB |
testcase_20 | AC | 590 ms
81,344 KB |
testcase_21 | AC | 584 ms
81,152 KB |
testcase_22 | AC | 510 ms
79,364 KB |
testcase_23 | AC | 1,068 ms
81,012 KB |
testcase_24 | AC | 1,479 ms
259,908 KB |
testcase_25 | AC | 909 ms
258,292 KB |
testcase_26 | AC | 1,391 ms
260,744 KB |
testcase_27 | AC | 194 ms
89,472 KB |
testcase_28 | AC | 236 ms
101,404 KB |
testcase_29 | AC | 195 ms
111,032 KB |
testcase_30 | AC | 169 ms
94,848 KB |
testcase_31 | AC | 970 ms
228,836 KB |
testcase_32 | AC | 138 ms
76,672 KB |
testcase_33 | AC | 258 ms
124,160 KB |
testcase_34 | AC | 69 ms
75,776 KB |
testcase_35 | AC | 73 ms
75,980 KB |
testcase_36 | AC | 66 ms
75,904 KB |
testcase_37 | AC | 83 ms
76,544 KB |
testcase_38 | AC | 81 ms
75,928 KB |
testcase_39 | AC | 74 ms
72,960 KB |
ソースコード
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<<self.bit self.multi=allow_multiple if query_number!=None: self.arc=[-1]*2*self.bit*(query_number+1) self.size=[0]*self.bit*(query_number+1) self.terminal=[0]*self.bit*(query_number+1) self.id=0 else: self.arc=[-1,-1] self.size=[0] self.terminal=[0] self.query_number=query_number self.v_list=[0]*(self.bit+1) self.lazy_xor=0 def xor_all(self, x): assert 0<=x<self.upper self.lazy_xor^=x def __ixor__(self, x): self.xor_all(x) return self def insert(self, x): """ x を追加する. """ assert 0<=x<self.upper x^=self.lazy_xor v=0 for i in reversed(range(self.bit)): d=(x>>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<self.upper): return x^=self.lazy_xor v=0 for i in reversed(range(self.bit)): d=(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<self.upper): return x^=self.lazy_xor v=0 for i in reversed(range(self.bit)): d=(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]<k): k=self.terminal[v] if 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<self.upper): return 0 x^=self.lazy_xor v=0 for i in reversed(range(self.bit)): d=(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<self.size[0]): return default v=0 res=0 for i in reversed(range(self.bit)): lc=self.arc[2*v] rc=self.arc[2*v+1] if (self.lazy_xor>>i)&1: lc,rc=rc,lc if lc==-1: v=rc res|=1<<i elif self.size[lc]<=k: k-=self.size[lc] v=rc res|=1<<i else: v=lc return res def get_min(self): return self.kth_element(1,1) def get_max(self): return self.kth_element(-1) def get_median(self, mode=0, func=None): """ 中央値を求める. [mode] 項の数が偶数のときの中央値の求め方を指定する (その 2値を a,b (a<=b) とする). mode=-1 → a mode= 0 → (a+b)/2 (float 型) mode= 1 → b mode=(その他) → その他 ( 2変数関数 func(a,b) で指定) """ if len(self)%2==1: return self.kth_element(len(self)//2) else: a=self.kth_element(len(self)//2) b=self.kth_element(len(self)//2-1) if mode==-1: return a elif mode==1: return b elif mode==0: return (a+b)/2 else: return func(a,b) def __getitem__(self, index): return self.kth_element(index) #================================================== def solve(): from operator import itemgetter from collections import defaultdict N,K,L,P=map(int,input().split()) A=[0]*N; B=[0]*N for i in range(N): A[i],B[i]=map(int,input().split()) def bit(x,k): return (x>>k)&1 def calc(C,D): T=[defaultdict(list) for _ in range(K+1)] N=len(C) for S in range(1<<N): cost=0; value=0; count=0 for i in range(N): if bit(S,i): cost+=C[i] count+=1 value+=D[i] if cost<=L and count<=K: T[count][cost].append(value) return [sorted(T[k]) for k in range(K+1)], T F0,G0=calc(A[:N//2], B[:N//2]) F1,G1=calc(A[N//2:], B[N//2:]) T=[Binary_Trie(4*10**10, True) for _ in range(K+1)] for k in range(K+1): t=T[k] for c in F1[k]: for w in G1[k][c]: t.insert(w) F=[] for k in range(K+1): F.extend([(cost,k) for cost in F0[k]]) F.sort(key=itemgetter(0)) X=0 for cost,k in F: for r in range(K+1): while F1[r] and cost+F1[r][-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())