結果
問題 | No.263 Common Palindromes Extra |
ユーザー | 草苺奶昔 |
提出日時 | 2024-02-18 02:27:23 |
言語 | Go (1.22.1) |
結果 |
MLE
|
実行時間 | - |
コード長 | 2,793 bytes |
コンパイル時間 | 13,908 ms |
コンパイル使用メモリ | 231,704 KB |
実行使用メモリ | 248,472 KB |
最終ジャッジ日時 | 2024-09-29 00:01:04 |
合計ジャッジ時間 | 13,812 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 8 ms
6,820 KB |
testcase_01 | AC | 1 ms
6,820 KB |
testcase_02 | AC | 2 ms
6,816 KB |
testcase_03 | AC | 19 ms
10,244 KB |
testcase_04 | AC | 76 ms
26,896 KB |
testcase_05 | AC | 95 ms
26,784 KB |
testcase_06 | AC | 9 ms
7,876 KB |
testcase_07 | AC | 220 ms
83,372 KB |
testcase_08 | AC | 235 ms
85,240 KB |
testcase_09 | AC | 334 ms
137,408 KB |
testcase_10 | MLE | - |
testcase_11 | AC | 67 ms
26,580 KB |
ソースコード
package main import ( "bufio" "fmt" "os" ) func main() { yuki263() } // No.263 Common Palindromes Extra // 求两个字符串的公共回文子串的个数 n<=5e5 // https://yukicoder.me/problems/no/263 func yuki263() { in := bufio.NewReader(os.Stdin) out := bufio.NewWriter(os.Stdout) defer out.Flush() var s, t string fmt.Fscan(in, &s, &t) T := NewPam() T.AddString(s + "><" + t) dps := make([]int, T.Size()) dpt := make([]int, T.Size()) lenS := int32(len(s)) for i := 0; i < T.Size(); i++ { for _, j := range T.Nodes[i].Indexes { // 回文出现位置 if j < lenS { dps[i]++ } else if j >= lenS+2 { dpt[i]++ } } } res := 0 for i := T.Size() - 1; i >= 2; i-- { // 按照拓扑序遍历本质不同回文 res += dps[i] * dpt[i] dps[T.Nodes[i].Link] += dps[i] dpt[T.Nodes[i].Link] += dpt[i] } fmt.Fprintln(out, res) } type Node struct { Next map[int32]int32 // 子节点. Link int32 // suffix link,指向当前回文串的最长真回文后缀的位置 Length int32 // 结点代表的回文串的长度 Indexes []int32 // 哪些位置的最长回文后缀 } type Pam struct { Ords []int32 Nodes []*Node lastPos int32 // 当前字符串(原串前缀)的最长回文后缀 } func NewPam() *Pam { res := &Pam{} res.Nodes = append(res.Nodes, res.newNode(0, -1)) // 奇根,长为 -1 res.Nodes = append(res.Nodes, res.newNode(0, 0)) // 偶根,长为 0 return res } func (pt *Pam) Add(x int32) int { pos := int32(len(pt.Ords)) pt.Ords = append(pt.Ords, x) cur := pt.findPrevPalindrome(pt.lastPos) _, hasKey := pt.Nodes[cur].Next[x] if !hasKey { pt.Nodes[cur].Next[x] = int32(len(pt.Nodes)) } pt.lastPos = pt.Nodes[cur].Next[x] if !hasKey { pt.Nodes = append(pt.Nodes, pt.newNode(-1, pt.Nodes[cur].Length+2)) if pt.Nodes[len(pt.Nodes)-1].Length == 1 { pt.Nodes[len(pt.Nodes)-1].Link = 1 } else { pt.Nodes[len(pt.Nodes)-1].Link = pt.Nodes[pt.findPrevPalindrome(pt.Nodes[cur].Link)].Next[x] } } pt.Nodes[pt.lastPos].Indexes = append(pt.Nodes[pt.lastPos].Indexes, pos) return int(pt.lastPos) } func (pt *Pam) AddString(s string) { if len(s) == 0 { return } for _, v := range s { pt.Add(v) } } func (pt *Pam) Size() int { return len(pt.Nodes) } func (pt *Pam) GetNode(pos int) *Node { return pt.Nodes[pos] } func (pt *Pam) newNode(link, length int32) *Node { return &Node{ Next: make(map[int32]int32), Link: link, Length: length, } } func (pt *Pam) findPrevPalindrome(cur int32) int32 { pos := int32(len(pt.Ords) - 1) for { rev := pos - 1 - pt.Nodes[cur].Length // !插入当前字符的条件str[i]==str[i-len-1] if rev >= 0 && pt.Ords[rev] == pt.Ords[len(pt.Ords)-1] { break } cur = pt.Nodes[cur].Link } return cur }