結果
問題 | No.599 回文かい |
ユーザー |
👑 |
提出日時 | 2020-05-01 23:47:33 |
言語 | Lua (LuaJit 2.1.1734355927) |
結果 |
AC
|
実行時間 | 480 ms / 4,000 ms |
コード長 | 5,047 bytes |
コンパイル時間 | 264 ms |
コンパイル使用メモリ | 5,376 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-12-25 15:38:39 |
合計ジャッジ時間 | 4,030 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 22 |
ソースコード
local mfl, mce = math.floor, math.ceillocal mmi, mma = math.min, math.maxlocal mod = 1000000007local function bmul(x, y)local x1, y1 = mfl(x / 31623), mfl(y / 31623)local x0, y0 = x - x1 * 31623, y - y1 * 31623return (x1 * y1 * 14122 + (x1 * y0 + x0 * y1) * 31623 + x0 * y0) % modendlocal function badd(x, y)return (x + y) % modendlocal TranSufA = {}TranSufA.makeSufA = function(self)self.sufa = {}local n = #self.strlocal idx, tbl1, tbl2 = self.sufa, {}, {}local tmp_tbl = {}for i = 1, n doidx[i] = itbl1[i] = self.str:sub(i, i):byte() - 95 -- "a" = 97tbl2[i] = 0tmp_tbl[i] = 0endidx[n + 1], tbl1[n + 1], tbl2[n + 1] = n + 1, 1, 0n = n + 1 -- add empty to lasttable.sort(idx, function(a, b) return tbl1[a] < tbl1[b] end)local step, stepflag = 1, truewhile step < n dolocal v = stepflag and tbl1 or tbl2local vd = stepflag and tbl2 or tbl1stepflag = not stepflaglocal stepdst = {}for i = 1, n dolocal dst = i + stepif n < dst then dst = dst - n endstepdst[i] = dstendlocal left, major = 1, v[idx[1]]local minor_min = v[stepdst[idx[1]]]local minor_max = minor_minlocal minormap = {}local cur = 0for i = 1, n dolocal minor = v[stepdst[idx[i]]]if minormap[minor] then minormap[minor] = minormap[minor] + 1else minormap[minor] = 1endminor_min, minor_max = mmi(minor_min, minor), mma(minor_max, minor)local isend = i == n or major ~= v[idx[i + 1]]if isend thenlocal right = iif left == right thencur = cur + 1vd[idx[left]] = curelseif minor_min ~= minor_max thenlocal minortbl = {}for k, _u in pairs(minormap) do table.insert(minortbl, k) endtable.sort(minortbl)local offset = 0for i = 1, #minortbl dolocal cnt = minormap[minortbl[i]]minormap[minortbl[i]] = iminortbl[i] = offset -- reuseoffset = offset + cntendfor j = left, right dolocal idxj = idx[j]local minor_idx = minormap[v[stepdst[idxj]]]local ofst = minortbl[minor_idx]ofst = ofst + 1minortbl[minor_idx] = ofsttmp_tbl[ofst] = idxjvd[idxj] = cur + minor_idxendcur = cur + #minortblfor j = left, right doidx[j] = tmp_tbl[j - left + 1]endelsecur = cur + 1for j = left, right dovd[idx[j]] = curendendif i < n thenleft, major = i + 1, v[idx[i + 1]]minor_min = v[stepdst[idx[i + 1]]]minor_max = minor_minminormap = {}endendendstep = step * 2end-- remove empty from first (O(N))table.remove(self.sufa, 1)n = n - 1self.sufa_inv = {}for i = 1, n do self.sufa_inv[i] = 0 endfor i = 1, n doself.sufa_inv[self.sufa[i]] = iendendTranSufA.makeLCPA = function(self)assert(self.sufa)local n = #self.sufaself.lcpa = {}local str, sufa, lcpa = self.str, self.sufa, self.lcpafor i = 1, n - 1 do lcpa[i] = 0 endlocal spos = 0for i = 1, n dolocal lcppos = self.sufa_inv[i]if lcppos < n thenlocal len = sposlocal p1, p2 = sufa[lcppos], sufa[lcppos + 1]p1, p2 = p1 + spos, p2 + sposwhile p1 <= n and p2 <= n doif str:sub(p1, p1) == str:sub(p2, p2) thenlen = len + 1p1, p2 = p1 + 1, p2 + 1else breakendendlcpa[lcppos] = lenspos = mma(0, len - 1)endendendTranSufA.create = function(self, str)self.str = strself:makeSufA()self:makeLCPA()endTranSufA.new = function(str)local obj = {}setmetatable(obj, {__index = TranSufA})obj:create(str)return objendlocal s = io.read()local sa = TranSufA.new(s)-- print(table.concat(sa.sufa, " "))-- print(table.concat(sa.sufa_inv, " "))-- print(table.concat(sa.lcpa, " "))local n = #slocal hn = mfl(n / 2)local offset = #s - hnlocal dp = {}for i = 1, hn + 1 dodp[i] = 1endfor i = 1, hn dolocal src = offset + ilocal sufa_pos = sa.sufa_inv[src]local rev_src = n + 1 - srclocal len = 1000000007local pos = sufa_poswhile pos < n dolocal dst = sa.sufa[pos + 1]len = mmi(len, sa.lcpa[pos])if dst <= rev_src and rev_src - dst + 1 <= len thenlocal dpsrc = i - 1local dpdst = i - 1 + (rev_src - dst + 1)dp[dpdst + 1] = badd(dp[dpdst + 1], dp[dpsrc + 1])endpos = pos + 1endlen = 1000000007pos = sufa_poswhile 1 < pos dolocal dst = sa.sufa[pos - 1]len = mmi(len, sa.lcpa[pos - 1])if dst <= rev_src and rev_src - dst + 1 <= len thenlocal dpsrc = i - 1local dpdst = i - 1 + (rev_src - dst + 1)dp[dpdst + 1] = badd(dp[dpdst + 1], dp[dpsrc + 1])endpos = pos - 1endendprint(dp[hn + 1])