結果
問題 | No.2901 Logical Sum of Substring |
ユーザー | None |
提出日時 | 2024-05-12 13:38:31 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,296 bytes |
コンパイル時間 | 483 ms |
コンパイル使用メモリ | 82,176 KB |
実行使用メモリ | 222,156 KB |
最終ジャッジ日時 | 2024-09-20 20:51:19 |
合計ジャッジ時間 | 16,692 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 87 ms
82,176 KB |
testcase_01 | AC | 83 ms
76,544 KB |
testcase_02 | AC | 261 ms
79,064 KB |
testcase_03 | AC | 267 ms
78,772 KB |
testcase_04 | AC | 254 ms
79,320 KB |
testcase_05 | AC | 261 ms
79,076 KB |
testcase_06 | AC | 271 ms
78,788 KB |
testcase_07 | AC | 261 ms
79,028 KB |
testcase_08 | TLE | - |
testcase_09 | TLE | - |
testcase_10 | TLE | - |
testcase_11 | TLE | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
testcase_22 | -- | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
testcase_29 | -- | - |
testcase_30 | -- | - |
testcase_31 | -- | - |
ソースコード
def merge(total, Ai): res=total[:] for p in range(K): res[p] += Ai[p] return res def inv_merge(total, Ai): res = total[:] for p in range(K): res[p] -= Ai[p] return res def is_impossible(total): return any(v <= 0 for v in total) def get_sum(l,r): """ [l,r) Lidx = [bitが変化するタイミング1, タイミング2,...] Lcnt = [[bit0の個数, bit1の個数, ...], ] """ kl=l//d # lにいるブロック番号 kr=r//d # rのいるブロック番号 if kl==kr: res=float("inf") Ridx=list(range(l,r)) Rcnt = [] for i in range(l,r): cnt = [0] * K for p in range(K): if (A[i] >> p) & 1 == 1: cnt[p] += 1 Rcnt.append(cnt[:]) Lidx=list(range(l,r)) Lcnt = [] for i in range(l,r)[::-1]: cnt = [0] * K for p in range(K): if (A[i] >> p) & 1 == 1: cnt[p] += 1 Lcnt.append(cnt[:]) Lcnt.reverse() else: res=float("inf") for k in range(kl+1,kr): res=min(X[k], res) Ridx=list(range(l,(kl+1)*d)) for k in range(kl+1,kr): Ridx+=R[k][0] Ridx+=list(range(kr*d,r)) Rcnt=[] for i in range(l,(kl+1)*d): cnt = [0] * K for p in range(K): if (A[i]>>p)&1==1: cnt[p]+=1 Rcnt.append(cnt[:]) for k in range(kl+1,kr): Rcnt+=R[k][1] for i in range(kr*d,r): cnt = [0] * K for p in range(K): if (A[i]>>p)&1==1: cnt[p]+=1 Rcnt.append(cnt[:]) Lidx=list(range(l,(kl+1)*d)) for k in range(kl+1,kr): Lidx+=list(reversed(L[k][0])) Lidx+=list(range(kr*d,r)) Lcnt=[] for i in range(kr*d,r)[::-1]: cnt = [0] * K for p in range(K): if (A[i]>>p)&1==1: cnt[p]+=1 Lcnt.append(cnt[:]) for k in range(kl+1,kr)[::-1]: Lcnt+=L[k][1] for i in range(l,(kl+1)*d)[::-1]: cnt = [0] * K for p in range(K): if (A[i]>>p)&1==1: cnt[p]+=1 Lcnt.append(cnt[:]) Lcnt.reverse() right=0 total = [0]*K for left in range(len(Lidx)): while right < len(Ridx) and (is_impossible(total) or ((Ridx[right-1])//d<=Lidx[left]//d and kl+1<=Lidx[left]//d<kr) ): total = merge(total, Rcnt[right]) right += 1 if is_impossible(total): break res = min(Ridx[right-1]+1 - Lidx[left], res) total = inv_merge(total, Lcnt[left]) return res def eval_bucket(k): res = float("inf") total = [0] * K C = [[] for _ in range(d)] for i in range(d): cnt = [0] * K for p in range(K): if (A[d * k + i] >> p) & 1 == 1: cnt[p] += 1 C[i] = cnt[:] right = 0 for left in range(d): while right < d and is_impossible(total): total = merge(total, C[right]) right += 1 if is_impossible(total): break res = min(right - left, res) if right == left: right += 1 else: total = inv_merge(total, C[left]) return res def update(x,v): A[x]=v k=x//d R[k]=([],[]) L[k]=([],[]) total=0 cnt=[0]*K for i in range(d*k,d*(k+1)): for p in range(K): if (A[i]>>p)&1==1: cnt[p]+=1 if total|A[i]!=total: total|=A[i] R[k][0].append(i) R[k][1].append(cnt[:]) cnt = [0] * K total=0 cnt=[0]*K for i in range(d*k,d*(k+1))[::-1]: for p in range(K): if (A[i]>>p)&1==1: cnt[p]+=1 if total|A[i]!=total: total|=A[i] L[k][0].append(i) L[k][1].append(cnt[:]) cnt = [0] * K X[k]=eval_bucket(k) N,K=map(int, input().split()) A=list(map(int, input().split())) Q=int(input()) N2=1000 # number of buckets d=(N+N2-1)//N2 # bucket size A=A+[0]*(d*N2-N) X=[0]*N2 # bucket内全体の答え R=[([],[]) for _ in range(N2)] # (増えるタイミング, 増えるbitの個数) L=[([],[]) for _ in range(N2)] for k in range(N2): total=0 cnt=[0]*K for i in range(d*k,d*(k+1)): for p in range(K): if (A[i]>>p)&1==1: cnt[p]+=1 if total|A[i]!=total: total|=A[i] R[k][0].append(i) R[k][1].append(cnt[:]) cnt = [0] * K total=0 cnt=[0]*K for i in range(d*k,d*(k+1))[::-1]: for p in range(K): if (A[i]>>p)&1==1: cnt[p]+=1 if total|A[i]!=total: total|=A[i] L[k][0].append(i) L[k][1].append(cnt[:]) cnt = [0] * K X[k]=eval_bucket(k) for _ in range(Q): q=list(map(int, input().split())) if q[0]==1: x,v=q[1:] update(x-1,v) else: l,r=q[1:] res=get_sum(l-1,r) print(res if res!=float("inf") else -1)