結果

問題 No.2606 Mirror Relay
ユーザー 👑 seekworser
提出日時 2024-09-09 02:32:18
言語 Nim
(2.2.0)
結果
AC  
実行時間 316 ms / 2,000 ms
コード長 4,061 bytes
コンパイル時間 3,744 ms
コンパイル使用メモリ 66,460 KB
実行使用メモリ 83,932 KB
最終ジャッジ日時 2024-09-09 02:32:26
合計ジャッジ時間 8,036 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 69
権限があれば一括ダウンロードができます

ソースコード

diff #

import macros;macro ImportExpand(s:untyped):untyped = parseStmt($s[2])
# verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/problems/NTL_1_E
import strutils
import sequtils
import algorithm
ImportExpand "cplib/collections/palindromic_tree.nim" <=== "when not declared CPLIB_COLLECTIONS_PALINDROMIC_TREE:\n    const CPLIB_COLLECTIONS_PALINDROMIC_TREE* = 1\n    import sequtils\n    import algorithm\n    type PalindromicTreeNode* = object\n        link: seq[ref PalindromicTreeNode]\n        suffix_link: ref PalindromicTreeNode\n        len, count, id: int\n\n    type PalindromicTree* = object\n        amax: int\n        nodes: seq[ref PalindromicTreeNode]\n\n    proc len*(node: PalindromicTreeNode): int = node.len\n    proc count*(node: PalindromicTreeNode): int = node.count\n    proc id*(node: PalindromicTreeNode): int = node.id\n    proc suffix_link*(node: PalindromicTreeNode): ref PalindromicTreeNode = node.suffix_link\n    proc link*(node: PalindromicTreeNode): seq[ref PalindromicTreeNode] = node.link\n    proc nodes*(pt: PalindromicTree): seq[ref PalindromicTreeNode] = pt.nodes\n\n    proc newPalindromicTreeNode(pt: var PalindromicTree, amax, len: int): ref PalindromicTreeNode =\n        result = new PalindromicTreeNode\n        result[].link = newSeq[ref PalindromicTreeNode](amax)\n        result[].suffix_link = nil\n        result[].len = len\n        result[].count = 0\n        result[].id = pt.nodes.len\n        pt.nodes.add(result)\n\n    proc init(amax: int): PalindromicTree =\n        discard result.newPalindromicTreeNode(amax, -1)\n        discard result.newPalindromicTreeNode(amax, 0)\n        result.amax = amax\n        result.nodes[1][].suffix_link = result.nodes[0]\n\n\n    proc initPalindromicTree*(a: seq[int], amax: int = -1): PalindromicTree =\n        var amax = amax\n        if amax < 0: amax = a.max\n        result = init(amax)\n        proc find_longest(pos: int, node: ref PalindromicTreeNode): ref PalindromicTreeNode =\n            var ln = pos - node[].len - 1\n            if ln >= 0 and a[ln] == a[pos]:\n                return node\n            return find_longest(pos, node[].suffix_link)\n        var current_node = result.nodes[0]\n        for i in 0..<a.len:\n            current_node = find_longest(i, current_node)\n            if current_node[].link[a[i]] == nil:\n                current_node[].link[a[i]] = result.newPalindromicTreeNode(amax, current_node[].len + 2)\n            if current_node == result.nodes[0]:\n                current_node[].link[a[i]][].suffix_link = result.nodes[1]\n            else:\n                current_node[].link[a[i]][].suffix_link = find_longest(i, current_node[].suffix_link)[].link[a[i]]\n            current_node = current_node[].link[a[i]]\n            current_node[].count += 1\n\n    proc initPalindromicTree*(s: string, c: char = 'a'): PalindromicTree =\n        return initPalindromicTree(s.mapIt(int(it) - int(c)), 26)\n\n    proc get_palindrome*(pt: PalindromicTree, node: ref PalindromicTreeNode): seq[int] =\n        if node == pt.nodes[0] or node == pt.nodes[1]: return newSeq[int](0)\n        var ans = newSeq[int](0)\n        proc dfs(x: ref PalindromicTreeNode): bool =\n            if x == node: return true\n            for i in 0..<pt.amax:\n                if x[].link[i] == nil: continue\n                if dfs(x[].link[i]):\n                    ans.add(i)\n                    return true\n            return false\n        discard dfs(pt.nodes[0])\n        discard dfs(pt.nodes[1])\n        for i in ans.len..<node[].len:\n            ans.add(ans[node[].len-1-i])\n        return ans\n\n    proc update_count*(pt: PalindromicTree) =\n        for node in pt.nodes[1..<pt.nodes.len].reversed:\n            node[].suffix_link[].count += node[].count\n"

var s = stdin.readLine.reversed.join("")
var pt = initPalindromicTree(s)
pt.update_count

var score = newSeqWith(pt.nodes.len, 0)
for i in 1..<pt.nodes.len:
    var node = pt.nodes[i]
    score[i] = score[node[].suffix_link[].id] + node[].count * node[].len
echo score.max
0