結果
| 問題 |
No.1471 Sort Queries
|
| コンテスト | |
| ユーザー |
toyuzuko
|
| 提出日時 | 2021-04-17 19:09:51 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 117 ms / 2,000 ms |
| コード長 | 4,188 bytes |
| コンパイル時間 | 140 ms |
| コンパイル使用メモリ | 82,332 KB |
| 実行使用メモリ | 78,276 KB |
| 最終ジャッジ日時 | 2024-07-04 02:10:08 |
| 合計ジャッジ時間 | 4,699 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 37 |
ソースコード
class FullyIndexableDictionary():
def __init__(self, size):
self.size = size
self.block = (size + 31) >> 5
self.bit = [0] * self.block
self.sum = [0] * self.block
def popcount(self, x):
x = x - ((x >> 1) & 0x55555555)
x = (x & 0x33333333) + ((x >> 2) & 0x33333333)
x = x + (x >> 4) & 0x0f0f0f0f
x = x + (x >> 8)
x = x + (x >> 16)
return x & 0x0000007f
def set(self, k):
self.bit[k >> 5] |= 1 << (k & 31)
def build(self):
for i in range(1, self.block):
self.sum[i] = self.sum[i - 1] + self.popcount(self.bit[i - 1])
def access(self, k):
return (self.bit[k >> 5] >> (k & 31)) & 1
def rank(self, k, v):
r = self.sum[k >> 5] + self.popcount(self.bit[k >> 5] & ((1 << (k & 31)) - 1))
return r if v else k - r
def select(self, k, v):
if k < 0 or self.rank(self.size, v) <= k: return -1
l, r = 0, self.size
while r - l > 1:
m = (l + r) // 2
if self.rank(m, v) >= k + 1:
r = m
else:
l = m
return l
class WaveletMatrix():
def __init__(self, log=32):
self.size = 0
self.log = log
self.mat = [None] * log
self.mid = [None] * log
def build(self, arr):
self.size = len(arr)
for lv in range(self.log)[::-1]:
self.mat[lv] = FullyIndexableDictionary(self.size + 1)
lt = []
rt = []
for i, a in enumerate(arr):
if (a >> lv) & 1:
self.mat[lv].set(i)
rt.append(a)
else:
lt.append(a)
self.mid[lv] = len(lt)
self.mat[lv].build()
arr = lt + rt
def access(self, k):
res = 0
for lv in range(self.log)[::-1]:
if self.mat[lv].access(k):
res |= 1 << lv
k = self.mat[lv].rank(k, 1) + self.mid[lv]
else:
k = self.mat[lv].rank(k, 0)
return res
def rank(self, x, r):
l = 0
for lv in range(self.log)[::-1]:
if (x >> lv) & 1:
l = self.mat[lv].rank(l, 1) + self.mid[lv]
r = self.mat[lv].rank(r, 1) + self.mid[lv]
else:
l = self.mat[lv].rank(l, 0)
r = self.mat[lv].rank(r, 0)
return r - l
def select(self, x, k):
idx = 0
for lv in range(self.log)[::-1]:
if (x >> lv) & 1:
idx = self.mat[lv].rank(self.size, 0) + self.mat[lv].rank(idx, 1)
else:
idx = self.mat[lv].rank(idx, 0)
idx += k
for lv in range(self.log):
if (x >> lv) & 1:
idx = self.mat[lv].select(idx - self.mat[lv].rank(self.size, 0), 1)
else:
idx = self.mat[lv].select(idx, 0)
return idx
def freq(self, l, r, x):
res = 0
for lv in range(self.log)[::-1]:
if (x >> lv) & 1:
res += self.mat[lv].rank(r, 0) - self.mat[lv].rank(l, 0)
l = self.mat[lv].rank(l, 1) + self.mid[lv]
r = self.mat[lv].rank(r, 1) + self.mid[lv]
else:
l = self.mat[lv].rank(l, 0)
r = self.mat[lv].rank(r, 0)
return res
def quantile(self, l, r, k):
res = 0
for lv in range(self.log)[::-1]:
cnt = self.mat[lv].rank(r, 0) - self.mat[lv].rank(l, 0)
if cnt <= k:
res |= 1 << lv
k -= cnt
l = self.mat[lv].rank(l, 1) + self.mid[lv]
r = self.mat[lv].rank(r, 1) + self.mid[lv]
else:
l = self.mat[lv].rank(l, 0)
r = self.mat[lv].rank(r, 0)
return res
N, Q = map(int, input().split())
S = input()
arr = [ord(s) for s in S]
wm = WaveletMatrix(8)
wm.build(arr)
res = []
for _ in range(Q):
l, r, x = map(int, input().split())
l -= 1; r -= 1; x -= 1
x = wm.quantile(l, r + 1, x)
res.append(chr(x))
print('\n'.join(res))
toyuzuko