public static int CompareNodes(int parent, int v1, int v2, PalindromicTreeWithExample tree, string str) { var parentLen = tree.tree[parent].len; var left1 = tree.tree[v1].sampleLeft; var left2 = tree.tree[v2].sampleLeft; var len1 = tree.tree[v1].len; var len2 = tree.tree[v2].len; var i = parentLen; while (true) { if (i == len1 && i == len2) { return(0); } if (i == len1) { return(-1); } if (i == len2) { return(1); } var comp = str[i + left1].CompareTo(str[i + left2]); if (comp != 0) { return(comp); } i++; } }
public static Solut SolvePrepare(string str) { var palTree = new PalindromicTreeWithExample(str); var pows = new long[str.Length + 1]; pows[0] = 1L; for (var i = 1; i < pows.Length; i++) { pows[i] = pows[i - 1] * A % MOD; } var hashes = new long[palTree.num + 1]; var letters = new char[palTree.num + 1]; var revEdges = new int[palTree.num + 1]; var suffRevAdj = Create(palTree.num + 1, i => new List <int>()); { var queue = new Queue <int>(); queue.Enqueue(1); queue.Enqueue(2); while (queue.Count > 0) { var node = queue.Dequeue(); var suff = palTree.tree[node].sufflink; if (node > 2 && suff > 0) { suffRevAdj[suff].Add(node); } var adj = palTree.tree[node].next; for (var i = 0; i < adj.Length; i++) { if (adj[i] > 0) { var next = adj[i]; letters[next] = (char)('a' + i); revEdges[next] = node; queue.Enqueue(next); var c = (int)letters[next]; if (node == 1) { hashes[next] = c % MOD; } else if (node == 2) { hashes[next] = (c * pows[1] + c) % MOD; } else { var nodeHash = hashes[node]; var nextLen = palTree.tree[next].len; var nextHash = ((pows[nextLen - 1] * c) + (nodeHash * A) + c) % MOD; hashes[next] = nextHash; } } } } } //for (var i = 0; i < suffRevAdj.Length; i++) //{ // var adj = suffRevAdj[i]; // if (adj.Count <= 1) continue; // adj.Sort((v1, v2) => CompareNodes(i, v1, v2, palTree, str)); //} var sums = new long[palTree.num + 1]; foreach (var node in Traverse_Tree_PostOrder_NonRec(2, v => suffRevAdj[v])) { var sum = palTree.tree[node].num; foreach (var next in suffRevAdj[node]) { sum += sums[next]; } sums[node] = sum; } return(new Solut { PalTree = palTree, Str = str, SuffRevAdj = suffRevAdj, Sums = sums, Hashes = hashes, IsSuffRevAdjSorted = new bool[palTree.num + 1] }); }