Example #1
0
        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++;
            }
        }
Example #2
0
        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]
            });
        }