結果

問題 No.800 四平方定理
ユーザー 👑 obakyanobakyan
提出日時 2019-06-06 22:04:31
言語 Lua
(LuaJit 2.1.1696795921)
結果
WA  
実行時間 -
コード長 2,476 bytes
コンパイル時間 30 ms
コンパイル使用メモリ 6,688 KB
実行使用メモリ 19,476 KB
最終ジャッジ日時 2024-04-09 19:25:06
合計ジャッジ時間 16,260 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 AC 14 ms
6,816 KB
testcase_02 WA -
testcase_03 AC 11 ms
6,940 KB
testcase_04 WA -
testcase_05 WA -
testcase_06 AC 16 ms
6,940 KB
testcase_07 WA -
testcase_08 AC 13 ms
6,940 KB
testcase_09 WA -
testcase_10 WA -
testcase_11 AC 495 ms
11,136 KB
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 AC 656 ms
19,264 KB
testcase_19 AC 654 ms
19,288 KB
testcase_20 AC 1 ms
6,940 KB
testcase_21 AC 1 ms
6,944 KB
testcase_22 WA -
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 AC 1 ms
6,940 KB
testcase_27 AC 2 ms
6,944 KB
testcase_28 AC 778 ms
19,256 KB
testcase_29 AC 941 ms
19,232 KB
testcase_30 WA -
testcase_31 AC 727 ms
19,264 KB
testcase_32 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

local mfl = math.floor
local mmi = math.min
local function lower_bound(ary, x, max)
  local num = #ary
  if num == 0 then return 1 end
  if(x <= ary[1]) then return 1 end
  if(ary[max] < x) then return max + 1 end
  local min = 1
  while(1 < max - min) do
    local mid = mfl((min + max) / 2)
    if(ary[mid] < x) then
      min = mid
    else
      max = mid
    end
  end
  return max
end

local n, d = io.read("*n", "*n")
local sq = {}
local same_ev, same_odd = {}, {}
local same_evlen, same_oddlen = 0, 0
for i = 1, n do
  sq[i] = i * i
  if 2 * sq[i] < d + n * n then
    if i % 2 == 0 then
      same_evlen = same_evlen + 1
      same_ev[same_evlen] = 2 * sq[i]
    else
      same_oddlen = same_oddlen + 1
      same_odd[same_oddlen] = 2 * sq[i]
    end
  end
end
local evens, odds, evod = {}, {}, {}
local evlen, odlen, eolen = 0, 0, 0
for i = 1, n - 1 do
  for j = i + 2, n, 2 do
    if d + n * n <= sq[i] + sq[j] then break end
    if i % 2 == 0 then
      evlen = evlen + 1
      evens[evlen] = sq[i] + sq[j]
    else
      odlen = odlen + 1
      odds[odlen] = sq[i] + sq[j]
    end
  end
  for j = i + 1, n, 2 do
    if d + n * n <= sq[i] + sq[j] then break end
    eolen = eolen + 1
    evod[eolen] = sq[i] + sq[j]
  end
end
table.sort(evens)
table.sort(odds)
local cnt = 0
for w = 1, n do
  local w2d = d + sq[w]
  local curmax_odd, curmax_even, curmax_evod = odlen, evlen, eolen
  for z = 1, n do
    local tgt = w2d - sq[z]
    if tgt <= 0 then break end
    if tgt % 4 == 0 then
      local a = lower_bound(same_ev, tgt, same_evlen)
      if a <= same_evlen and same_ev[a] == tgt then
        cnt = cnt + 1
      end
      a = lower_bound(evens, tgt, curmax_even)
      curmax_even = mmi(evlen, a)
      for k = a, evlen do
        if evens[k] == tgt then
          cnt = cnt + 2
        else break
        end
      end
    elseif tgt % 8 == 2 then
      local a = lower_bound(same_odd, tgt, same_oddlen)
      if a <= same_oddlen and same_odd[a] == tgt then
        cnt = cnt + 1
      end
      a = lower_bound(odds, tgt, curmax_odd)
      curmax_odd = mmi(odlen, a)
      for k = a, odlen do
        if odds[k] == tgt then
          cnt = cnt + 2
        else break
        end
      end
    elseif tgt % 4 == 1 then
      local a = lower_bound(evod, tgt, curmax_evod)
      curmax_evod = mmi(eolen, a)
      for k = a, eolen do
        if evod[k] == tgt then
          cnt = cnt + 2
        else break
        end
      end
    end
  end
end
print(cnt)
0