結果
問題 | No.1332 Range Nearest Query |
ユーザー |
|
提出日時 | 2022-03-31 23:06:11 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,613 ms / 2,500 ms |
コード長 | 4,412 bytes |
コンパイル時間 | 415 ms |
コンパイル使用メモリ | 82,176 KB |
実行使用メモリ | 280,000 KB |
最終ジャッジ日時 | 2024-11-17 16:20:35 |
合計ジャッジ時間 | 52,208 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 48 |
ソースコード
#WaveletMatrixclass BitVector():def __init__(self,A):self.n = len(A)SA = [0] * (self.n + 1)for i,a in enumerate(A):SA[i+1] = SA[i] + aself.SA = SAdef rank1(self,r):return self.SA[r]def rank0(self,r):return r - self.SA[r]def select0(self,k):l,r = 0,len(self,SA)if not k < r - 1 - self.SA[r-1]:return -1while r - l > 1:m = l + r >> 1if m - self.SA[m] <= k:l = melse:r = mreturn ldef select1(self,k):l,r = 0,len(self.SA)if not k < self.SA[r-1]:return -1while r - l > 1:m = l + r >> 1if self.SA[m] <= k:l = melse:r = mreturn lclass WaveletMatrix():# s: word size. Ai <= 10**6 なら 20# Ai <= 10**9 なら 30 ぐらいで# (word size < 1 << s となるよう)def __init__(self,s,A):self.s = sself.A = Aself.n = len(A)self.X = []B = A.copy()for i in reversed(range(s)):mask = 1 << iL = []R = []T = []for a in B:if a & mask:T.append(1)R.append(a)else:T.append(0)L.append(a)vb = BitVector(T)self.X.append((vb.rank0(self.n),vb))B = L + Rself.X = self.X[::-1]def access(self,i):return self.A[i]# A[l,r)内のvalueの数を求めるdef rank(self,l,r,value):if l >= r:return 0for i in reversed(range(self.s)):z,vb = self.X[i]if value >> i & 1:l = z + vb.rank1(l)r = z + vb.rank1(r)else:l = vb.rank0(l)r = vb.rank0(r)return r - ldef select(self,value,k):#A内のk番目のvalueのindexを返す#value が k個なければ-1を返すif self.rank(0,self.n,value) <= k:return -1ind = 0for i in reversed(range(self.s)):z,v = self.X[i]if value >> 1 & 1:ind = z + vb.rank1(ind)else:ind = vb.rank0(int)ind += kfor i in range(self.s):z,vb = self.X[i]if ind < z:ind = vb.select0(ind)else:ind = vb.select1(ind-z)return inddef freq_to(self,l,r,value):# 0 <= A[i] < value な 数を求めるif not value:return 0if l >= r:return 0ret = 0for i in reversed(range(self.s)):z,vb = self.X[i]if value >> i & 1:ret += vb.rank0(r) - vb.rank0(l)l = z + vb.rank1(l)r = z + vb.rank1(r)else:l = vb.rank0(l)r = vb.rank0(r)return retdef freq(self,l,r,d,u):# d <= A[i] < u なる数を求めるif d >= u:return 0return self.freq_to(l,r,u) - self.freq_to(l,r,d)def quantile(self,l,r,k):# [l,r) のk番目に小さい数の返す# k: 0-index k = 0で一番小さい数を返すif k >= r - l:return -1ret = 0for i in reversed(range(self.s)):z,vb = self.X[i]zeros = vb.rank0(r) - vb.rank0(l)if zeros > k:l = vb.rank0(l)r = vb.rank0(r)else:k -= zerosret |= 1 << il = z + vb.rank1(l)r = z + vb.rank1(r)return retdef quantile2(self,l,r,k):#[l,r)のk番目に大きい数を返す# k: 0-indexreturn self.quantile(l,r,r-l-k-1)import sysrr = sys.stdinN = int(rr.readline())X = list(map(int,rr.readline().split()))Q = int(rr.readline())inf = 10 ** 9 + 5wm = WaveletMatrix(30,X)for _ in range(Q):l,r,x = map(int,rr.readline().split())t = wm.freq_to(l-1,r,x+1)ans = infif t > 0:u = wm.quantile(l-1,r,t-1)ans = x - uif t < r - l + 1:s = wm.quantile(l-1,r,t)ans = min(ans,s - x)print(ans)