結果

問題 No.911 ラッキーソート
ユーザー 👑 obakyanobakyan
提出日時 2020-04-18 16:56:54
言語 Lua
(LuaJit 2.1.1696795921)
結果
TLE  
実行時間 -
コード長 3,101 bytes
コンパイル時間 168 ms
コンパイル使用メモリ 6,944 KB
実行使用メモリ 332,668 KB
最終ジャッジ日時 2024-10-03 23:58:23
合計ジャッジ時間 6,515 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
10,496 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 3 ms
5,248 KB
testcase_04 AC 3 ms
5,248 KB
testcase_05 AC 3 ms
5,248 KB
testcase_06 AC 3 ms
5,248 KB
testcase_07 AC 3 ms
5,248 KB
testcase_08 AC 3 ms
5,248 KB
testcase_09 AC 3 ms
5,248 KB
testcase_10 AC 2 ms
5,248 KB
testcase_11 AC 2 ms
5,248 KB
testcase_12 AC 2 ms
5,248 KB
testcase_13 TLE -
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 -- -
testcase_32 -- -
testcase_33 -- -
testcase_34 -- -
testcase_35 -- -
testcase_36 -- -
testcase_37 -- -
testcase_38 -- -
testcase_39 -- -
testcase_40 -- -
testcase_41 -- -
testcase_42 -- -
testcase_43 -- -
testcase_44 -- -
testcase_45 -- -
testcase_46 -- -
testcase_47 -- -
testcase_48 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

local band = bit.band
local function lltonumber(str)
  local ret = 0LL
  for i = 1, #str do
    ret = ret * 10LL + str:sub(i, i):byte() - 48
  end
  return ret
end
local n, l, r = io.read():match("(%d+) (%d+) (%d+)")
n = tonumber(n)
l = lltonumber(l)
r = lltonumber(r)
local t = {}
local countlim = 64
-- 1 or 3: can use "0", 2 or 3: can use "1"
for i = 1, countlim do
  t[i] = 3
end
local astr_all = io.read()
local allbits = {}
for astr in astr_all:gmatch("%d+") do
  local a = lltonumber(astr)
  allbits[#allbits + 1] = {}
  local i = #allbits
  for j = 1, countlim do
    allbits[i][j] = a % 2LL == 1LL and 1 or 0
    a = a / 2LL
  end
end
local valid = true
local tasks = {{countlim, 1, n}}
while 0 < #tasks do
  local pos, left, right = tasks[#tasks][1], tasks[#tasks][2], tasks[#tasks][3]
  table.remove(tasks)
  if left == right then
    if 1 < pos then
      table.insert(tasks, {pos - 1, left, right})
    end
  else
    local lval = allbits[left][pos]
    local rval = allbits[right][pos]
    if lval == rval then
      for i = left + 1, right - 1 do
        if allbits[i][pos] ~= lval then
          valid = false break
        end
      end
      if not valid then break end
      if 1 < pos then
        table.insert(tasks, {pos - 1, left, right})
      end
    else
      local turnpos = nil
      for i = left + 1, right do
        if allbits[i][pos] ~= allbits[i - 1][pos] then
          if turnpos then valid = false break
          else
            turnpos = i
          end
        end
      end
      if not valid then break end
      if lval == 0 then
        t[pos] = band(t[pos], 1)
      else
        t[pos] = band(t[pos], 2)
      end
      if t[pos] == 0 then valid = false break end
      if pos ~= 1 then
        table.insert(tasks, {pos - 1, left, turnpos - 1})
        table.insert(tasks, {pos - 1, turnpos, right})
      end
    end
  end
end
-- print(valid)
-- print(table.concat(t, " "))
local function getCount(max)
  local maxbits = {}
  for i = 1, countlim do
    maxbits[i] = max % 2LL == 1LL and 1 or 0
    max = max / 2LL
  end
  local dpmax, dpnormal = {}, {}
  for i = 1, countlim do
    dpmax[i] = 0
    dpnormal[i] = 0
  end
  dpmax[countlim] = 1LL
  dpnormal[countlim] = 0LL
  for i = countlim - 1, 1, -1 do
    if t[i] == 3 then
      dpmax[i] = dpmax[i + 1]
      dpnormal[i] = dpnormal[i + 1] * 2LL
      if maxbits[i] == 1 then
        dpnormal[i] = dpnormal[i] + dpmax[i + 1]
      end
    elseif t[i] == 2 then
      -- only "1" is available
      if maxbits[i] == 0 then
        dpmax[i] = 0
      else
        dpmax[i] = dpmax[i + 1]
      end
      dpnormal[i] = dpnormal[i + 1]
    else -- t[i] == 1
      -- only "0" is available
      if maxbits[i] == 0 then
        dpmax[i] = dpmax[i + 1]
        dpnormal[i] = dpnormal[i + 1]
      else
        dpmax[i] = 0
        dpnormal[i] = dpnormal[i + 1] + dpmax[i + 1]
      end
    end
  end
  return dpnormal[1] + dpmax[1]
end
if valid then
  local cnt = getCount(r)
  if 0 < l then
    cnt = cnt - getCount(l - 1)
  end
  local str = tostring(cnt):gsub("LL", "")
  print(str)
else
  print(0)
end
0