結果
| 問題 |
No.876 Range Compress Query
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-02-28 13:46:22 |
| 言語 | Lua (LuaJit 2.1.1734355927) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,042 bytes |
| コンパイル時間 | 29 ms |
| コンパイル使用メモリ | 6,688 KB |
| 実行使用メモリ | 11,596 KB |
| 最終ジャッジ日時 | 2024-10-13 16:24:25 |
| 合計ジャッジ時間 | 4,808 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 14 WA * 4 |
ソースコード
local mfl, mce, mmi = math.floor, math.ceil, math.min
local mma = math.max
local LazySegTree = {}
LazySegTree.create = function(self, n, func, emptyvalue)
self.func, self.emptyvalue = func, emptyvalue
local stagenum, mul = 1, 1
self.cnt, self.size = {1}, {}
self.lazy = {{emptyvalue}}
while mul < n do
mul, stagenum = mul * 2, stagenum + 1
self.cnt[stagenum] = mul
self.lazy[stagenum] = {}
for i = 1, mul do self.lazy[stagenum][i] = emptyvalue end
end
for i = 1, stagenum do self.size[i] = self.cnt[stagenum + 1 - i] end
self.stagenum = stagenum
end
LazySegTree.getValue = function(self, idx)
for stage = 1, self.stagenum - 1 do
local pos = mce(idx / (self.size[stage]))
local v = self.lazy[stage][pos]
if v ~= self.emptyvalue then
self.lazy[stage + 1][pos * 2 - 1] = self.lazy[stage + 1][pos * 2 - 1] + v
self.lazy[stage + 1][pos * 2] = self.lazy[stage + 1][pos * 2] + v
end
end
return self.lazy[self.stagenum][idx]
end
LazySegTree.addRange = function(self, left, right, value)
if left == right then self.lazy[self.stagenum][left] = self.lazy[self.stagenum][left] + value return end
local start_stage = 1
while right - left + 1 < self.size[start_stage] do
start_stage = start_stage + 1
end
local t1, t2, t3 = {start_stage}, {left}, {right}
while 0 < #t1 do
local stage, l, r = t1[#t1], t2[#t1], t3[#t1]
table.remove(t1) table.remove(t2) table.remove(t3)
local sz = self.size[stage]
if (l - 1) % sz ~= 0 then
local newr = mmi(r, mce((l - 1) / sz) * sz)
table.insert(t1, stage + 1) table.insert(t2, l) table.insert(t3, newr)
l = newr + 1
end
if sz <= r + 1 - l then
self.lazy[stage][mce(l / sz)] = self.lazy[stage][mce(l / sz)] + value
l = l + sz
end
if l <= r then
table.insert(t1, stage + 1) table.insert(t2, l) table.insert(t3, r)
end
end
end
LazySegTree.new = function(n, func, emptyvalue)
local obj = {}
setmetatable(obj, {__index = LazySegTree})
obj:create(n, func, emptyvalue)
return obj
end
local SegTree = {}
SegTree.updateAll = function(self)
for i = self.stagenum - 1, 1, -1 do
for j = 1, self.cnt[i] 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.cnt, self.stage, self.size = {1}, {{}}, {}
while mul < n do
mul, stagenum = mul * 2, stagenum + 1
self.cnt[stagenum], self.stage[stagenum] = mul, {}
end
for i = 1, stagenum do self.size[i] = self.cnt[stagenum + 1 - i] 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 start_stage = 1
while right - left + 1 < self.size[start_stage] do
start_stage = start_stage + 1
end
local ret = self.emptyvalue
local t1, t2, t3 = {start_stage}, {left}, {right}
while 0 < #t1 do
local stage, l, r = t1[#t1], t2[#t1], t3[#t1]
table.remove(t1) table.remove(t2) table.remove(t3)
local sz = self.size[stage]
if (l - 1) % sz ~= 0 then
local newr = mmi(r, mce((l - 1) / sz) * sz)
table.insert(t1, stage + 1) table.insert(t2, l) table.insert(t3, newr)
l = newr + 1
end
if sz <= r + 1 - l then
ret = self.func(ret, self.stage[stage][mce(l / sz)])
l = l + sz
end
if l <= r then
table.insert(t1, stage + 1) table.insert(t2, l) table.insert(t3, r)
end
end
return ret
end
SegTree.setValue = function(self, idx, value)
self.stage[self.stagenum][idx] = value
for i = self.stagenum - 1, 1, -1 do
local dst = mce(idx / 2)
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
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 lst = LazySegTree.new(n, function(a, b) return a + b end, 0)
local st = SegTree.new(n, function(a, b) return a + b end, 0)
local prv = 0
for i = 1, n do
local a = io.read("*n")
lst:addRange(i, i, a)
if 1 < i then
if a ~= prv then
st:setValue(i, 1)
end
prv = a
end
end
for iq = 1, q do
local z = io.read("*n")
if z == 1 then
local l, r, x = io.read("*n", "*n", "*n")
lst:addRange(l, r, x)
if 1 < l then
local val_lm1 = lst:getValue(l - 1)
local val_l = lst:getValue(l)
st:setValue(l, val_l ~= val_lm1 and 1 or 0)
end
if r < n then
local val_rp1 = lst:getValue(r + 1)
local val_r = lst:getValue(r)
st:setValue(r + 1, val_r ~= val_rp1 and 1 or 0)
end
else
local l, r = io.read("*n", "*n")
local v = st:getRange(l, r)
if st:getRange(l, l) == 0 then v = v + 1 end
print(v)
end
end