結果

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

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 15 ms
6,816 KB
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 AC 35 ms
6,944 KB
testcase_08 AC 20 ms
6,944 KB
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 AC 878 ms
11,264 KB
testcase_15 AC 1,133 ms
11,136 KB
testcase_16 AC 889 ms
11,136 KB
testcase_17 AC 904 ms
11,136 KB
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 AC 1 ms
6,944 KB
testcase_22 AC 1,308 ms
19,316 KB
testcase_23 TLE -
testcase_24 AC 1,611 ms
19,300 KB
testcase_25 TLE -
testcase_26 AC 1 ms
6,944 KB
testcase_27 AC 2 ms
6,944 KB
testcase_28 WA -
testcase_29 WA -
testcase_30 AC 1,685 ms
19,264 KB
testcase_31 WA -
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 evens = {}
local odds = {}
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 evlen, odlen = 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
    evlen = evlen + 1
    evens[evlen] = sq[i] + sq[j]
  end
  for j = i + 1, n, 2 do
    if d + n * n <= sq[i] + sq[j] then break end
    odlen = odlen + 1
    odds[odlen] = 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 = odlen, evlen
  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
    elseif tgt % 4 == 1 then
      local 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
    end
  end
end
print(cnt)
0