結果

問題 No.878 Range High-Element Query
ユーザー 👑 obakyanobakyan
提出日時 2020-04-19 11:23:45
言語 Lua
(LuaJit 2.1.1696795921)
結果
AC  
実行時間 631 ms / 2,000 ms
コード長 7,991 bytes
コンパイル時間 222 ms
コンパイル使用メモリ 7,068 KB
実行使用メモリ 28,672 KB
最終ジャッジ日時 2024-04-15 06:55:59
合計ジャッジ時間 6,023 ms
ジャッジサーバーID
(参考情報)
judge2 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
6,812 KB
testcase_01 AC 7 ms
6,944 KB
testcase_02 AC 9 ms
6,944 KB
testcase_03 AC 7 ms
6,940 KB
testcase_04 AC 8 ms
6,940 KB
testcase_05 AC 9 ms
6,944 KB
testcase_06 AC 6 ms
6,944 KB
testcase_07 AC 6 ms
6,944 KB
testcase_08 AC 8 ms
6,940 KB
testcase_09 AC 10 ms
6,940 KB
testcase_10 AC 5 ms
6,944 KB
testcase_11 AC 618 ms
28,544 KB
testcase_12 AC 377 ms
22,016 KB
testcase_13 AC 469 ms
20,864 KB
testcase_14 AC 348 ms
17,408 KB
testcase_15 AC 398 ms
22,528 KB
testcase_16 AC 587 ms
27,520 KB
testcase_17 AC 631 ms
28,672 KB
testcase_18 AC 630 ms
28,544 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

local mfl, mce = math.floor, math.ceil
local mmi, mma = math.min, math.max
local bls, brs = bit.lshift, bit.rshift

local AvlTree = {}
AvlTree.makenode = function(self, val, parent)
  local i = self.box[#self.box]
  if not i then i = #self.v + 1
  else table.remove(self.box)
  end
  self.v[i], self.p[i] = val, parent
  self.lc[i], self.rc[i], self.l[i], self.r[i] = 0, 0, 1, 1
  return i
end
AvlTree.create = function(self, lessthan, n)
  self.lessthan = lessthan
  self.root = 1
  self.box = {}
  for i = n + 1, 2, -1 do table.insert(self.box, i) end
  -- value, leftCount, rightCount, left, right, parent
  self.v, self.lc, self.rc, self.l, self.r, self.p = {}, {}, {}, {}, {}, {}
  for i = 1, n + 1 do
    self.v[i], self.p[i] = 0, 1
    self.lc[i], self.rc[i], self.l[i], self.r[i] = 0, 0, 1, 1
  end
end

AvlTree.recalc = function(self, i)
  local kl, kr = self.l[i], self.r[i]
  if 1 < kl then self.lc[i] = 1 + mma(self.lc[kl], self.rc[kl])
  else self.lc[i] = 0
  end
  if 1 < kr then self.rc[i] = 1 + mma(self.lc[kr], self.rc[kr])
  else self.rc[i] = 0
  end
end
AvlTree.recalcAll = function(self, i)
  while 1 < i do
    self:recalc(i)
    i = self.p[i]
  end
end

AvlTree.rotR = function(self, parent)
  local granp, child = self.p[parent], self.l[parent]
  self.r[child], self.l[parent] = parent, self.r[child]
  self.p[child], self.p[parent] = granp, child
  self.p[self.l[parent]] = parent
  if 1 < granp then
    if self.l[granp] == parent then
      self.l[granp] = child
    else
      self.r[granp] = child
    end
  else
    self.root = child
  end
end

AvlTree.rotL = function(self, parent)
  local granp, child = self.p[parent], self.r[parent]
  self.l[child], self.r[parent] = parent, self.l[child]
  self.p[child], self.p[parent] = granp, child
  self.p[self.r[parent]] = parent
  if 1 < granp then
    if self.r[granp] == parent then
      self.r[granp] = child
    else
      self.l[granp] = child
    end
  else
    self.root = child
  end
end

AvlTree.rotLR = function(self, lparent, rparent)
  local sp, sl, sr = self.p, self.l, self.r
  local granp, d = sp[rparent], sr[lparent]
  sp[lparent], sr[lparent] = d, sl[d]
  sp[rparent], sl[rparent] = d, sr[d]
  sp[sl[d]], sp[sr[d]] = lparent, rparent
  sp[d], sl[d], sr[d] = granp, lparent, rparent
  if 1 < granp then
    if sr[granp] == rparent then sr[granp] = d
    else sl[granp] = d
    end
  else self.root = d
  end
end

AvlTree.rotRL = function(self, rparent, lparent)
  local sp, sl, sr = self.p, self.l, self.r
  local granp, d = sp[lparent], sl[rparent]
  sp[rparent], sl[rparent] = d, sr[d]
  sp[lparent], sr[lparent] = d, sl[d]
  sp[sr[d]], sp[sl[d]] = rparent, lparent
  sp[d], sr[d], sl[d] = granp, rparent, lparent
  if 1 < granp then
    if sl[granp] == lparent then sl[granp] = d
    else sr[granp] = d
    end
  else self.root = d
  end
end

AvlTree.push = function(self, val)
  if self.root <= 1 then self.root = self:makenode(val, 1) return end
  local pos = self.root
  while true do
    if self.lessthan(val, self.v[pos]) then
      if 1 < self.l[pos] then
        pos = self.l[pos]
      else
        self.l[pos] = self:makenode(val, pos)
        pos = self.l[pos]
        break
      end
    else
      if 1 < self.r[pos] then
        pos = self.r[pos]
      else
        self.r[pos] = self:makenode(val, pos)
        pos = self.r[pos]
        break
      end
    end
  end
  while 1 < pos do
    local child, parent = pos, self.p[pos]
    if parent <= 1 then
      break
    end
    self:recalc(parent)
    local lcp_m_rcp = self.lc[parent] - self.rc[parent]
    if lcp_m_rcp % 2 ~= 0 then -- 1 or -1
      pos = parent
    elseif lcp_m_rcp == 2 then
      if self.lc[child] - 1 == self.rc[child] then
        self:rotR(parent)
        self:recalcAll(parent)
      else
        self:rotLR(child, parent)
        self:recalc(child)
        self:recalcAll(parent)
      end
      break
    elseif lcp_m_rcp == -2 then
      if self.rc[child] - 1 == self.lc[child] then
        self:rotL(parent)
        self:recalcAll(parent)
      else
        self:rotRL(child, parent)
        self:recalc(child)
        self:recalcAll(parent)
      end
      break
    else
      break
    end
  end
end

AvlTree.rmsub = function(self, node)
  while 1 < node do
    self:recalc(node)
    if self.lc[node] == self.rc[node] then
      node = self.p[node]
    elseif self.lc[node] + 1 == self.rc[node] then
      self:recalcAll(self.p[node])
      break
    else
      if self.lc[self.r[node]] == self.rc[self.r[node]] then
        self:rotL(node)
        self:recalcAll(node)
        break
      elseif self.lc[self.r[node]] + 1 == self.rc[self.r[node]] then
        local nr = self.r[node]
        self:rotL(node)
        self:recalc(node)
        node = nr
      else
        local nr = self.r[node]
        local nrl = self.l[nr]
        self:rotRL(nr, node)
        self:recalc(nr)
        self:recalc(node)
        node = nrl
      end
    end
  end
end

AvlTree.popif = function(self, x)
  local node = self.root
  if node <= 1 then return false end
  while 1 < self.l[node] do
    node = self.l[node]
  end
  local v = self.v[node]
  if self.lessthan(v, x) then
    local kp = self.p[node]
    self.p[self.r[node]] = kp
    if 1 < kp then
      self.l[kp] = self.r[node]
      self:rmsub(kp)
    else
      self.root = self.r[node]
    end
    table.insert(self.box, node)
    return v
  else
    return false
  end
end

AvlTree.new = function(lessthan, n)
  local obj = {}
  setmetatable(obj, {__index = AvlTree})
  obj:create(lessthan, n)
  return obj
end

local SegTree = {}
SegTree.updateAll = function(self)
  for i = self.stagenum - 1, 1, -1 do
    local cnt = bls(1, i - 1)
    for j = 1, cnt do
      self.stage[i][j] = self.func(self.stage[i + 1][j * 2 - 1], self.stage[i + 1][j * 2])
    end
  end
end
SegTree.create = function(self, n, func, emptyvalue)
  self.func, self.emptyvalue = func, emptyvalue
  local stagenum, mul = 1, 1
  self.stage = {{}}
  while mul < n do
    mul, stagenum = mul * 2, stagenum + 1
    self.stage[stagenum] = {}
  end
  self.stagenum = stagenum
  for i = 1, mul do self.stage[stagenum][i] = emptyvalue end
  self:updateAll()
end
SegTree.getRange = function(self, left, right)
  if left == right then return self.stage[self.stagenum][left] end
  local stagenum = self.stagenum
  local ret = self.emptyvalue
  while left <= right do
    local stage, sz = 1, bls(1, stagenum - 1)
    local len = right - left + 1
    while (left - 1) % sz ~= 0 or len < sz do
      stage, sz = stage + 1, brs(sz, 1)
    end
    ret = self.func(ret, self.stage[stage][1 + brs(left - 1, stagenum - stage)])
    left = left + sz
  end
  return ret
end
SegTree.setValue = function(self, idx, value, silent)
  self.stage[self.stagenum][idx] = value
  if not silent then
    for i = self.stagenum - 1, 1, -1 do
      local dst = brs(idx + 1, 1)
      local rem = dst * 4 - 1 - idx
      self.stage[i][dst] = self.func(self.stage[i + 1][idx], self.stage[i + 1][rem])
      idx = dst
    end
  end
end
SegTree.new = function(n, func, emptyvalue)
  local obj = {}
  setmetatable(obj, {__index = SegTree})
  obj:create(n, func, emptyvalue)
  return obj
end

local n, q = io.read("*n", "*n")
local t = {}
for i = 1, n do
  t[i] = io.read("*n")
end
local queries = {}
for iq = 1, q do
  local _u = io.read("*n")
  queries[iq] = {io.read("*n", "*n")}
  queries[iq][3] = iq
end
table.sort(queries, function(a, b) return a[1] > b[1] end)
local st = SegTree.new(n, function(a, b) return a + b end, 0)
local avl = AvlTree.new(function(x, y) return t[x] < t[y] end, n)
local qpos = 1
for i = n, 1, -1 do
  local v = t[i]
  st:setValue(i, 1)
  local rmavl = avl:popif(i)
  while rmavl do
    st:setValue(rmavl, 0)
    rmavl = avl:popif(i)
  end
  avl:push(i)
  while qpos <= q and i <= queries[qpos][1] do
    queries[qpos][4] = st:getRange(i, queries[qpos][2])
    qpos = qpos + 1
  end
end

table.sort(queries, function(a, b) return a[3] < b[3] end)
for iq = 1, q do
  print(queries[iq][4])
end
0