Problem:
Score : 500 points

Problem Statement

Given are two strings s and t consisting of lowercase English letters. Determine if there exists an integer i satisfying the following condition, and find the minimum such i if it exists.

Let s' be the concatenation of 10^{100} copies of s. t is a subsequence of the string {s'}_1{s'}_2\ldots{s'}_i (the first i characters in s').

Notes

A subsequence of a string a is a string obtained by deleting zero or more characters from a and concatenating the remaining characters without changing the relative order. For example, the subsequences of contest include net, c, and contest.

Constraints

1 \leq |s| \leq 10^5

1 \leq |t| \leq 10^5

s and t consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

s
t

Output

If there exists an integer i satisfying the following condition, print the minimum such i; otherwise, print -1.

Sample Input 1

contest
son

Sample Output 1

10

t = son is a subsequence of the string contestcon (the first 10 characters in s' = contestcontestcontest...), so i = 10 satisfies the condition.

On the other hand, t is not a subsequence of the string contestco (the first 9 characters in s'), so i = 9 does not satisfy the condition.

Similarly, any integer less than 9 does not satisfy the condition, either. Thus, the minimum integer i satisfying the condition is 10.

Sample Input 2

contest
programming

Sample Output 2

-1

t = programming is not a substring of s' = contestcontestcontest.... Thus, there is no integer i satisfying the condition.

Sample Input 3

contest
sentence

Sample Output 3

33

Note that the answer may not fit into a 32-bit integer type, though we cannot put such a case here.

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

static class CodeJam
{
    class Treap<T> where T : IComparable
    {
        private class Node
        {
            private static Random g_rand = new Random();
            private readonly int m_rank = g_rand.Next();
            private readonly T m_value;
            private Node m_lch;
            private Node m_rch;
            private int m_count;

            public Node(T value)
            {
                m_value = value;
                m_count = 1;
            }

            private static int Count(Node node)
            {
                return (node != null) ? node.m_count : 0;
            }

            private Node Update()
            {
                m_count = Count(m_lch) + Count(m_rch) + 1;
                return this;
            }

            public static Node Merge(Node a, Node b)
            {
                if (a == null) { return b; }
                if (b == null) { return a; }

                if (a.m_rank < b.m_rank)
                {
                    a.m_rch = Merge(a.m_rch, b);
                    return a.Update();
                }
                else
                {
                    b.m_lch = Merge(a, b.m_lch);
                    return b.Update();
                }
            }

            public static Tuple<Node, Node> Split(Node t, int k)
            {
                if (t == null) { return new Tuple<Node, Node>(null, null); }

                if (k <= Count(t.m_lch))
                {
                    var pair = Split(t.m_lch, k);
                    t.m_lch = pair.Item2;
                    return new Tuple<Node, Node>(pair.Item1, t.Update());
                }
                else
                {
                    var pair = Split(t.m_rch, k - Count(t.m_lch) - 1);
                    t.m_rch = pair.Item1;
                    return new Tuple<Node, Node>(t.Update(), pair.Item2);
                }
            }

            public int FindIndex(T value)
            {
                int L = Count(m_lch);
                if (value.CompareTo(m_value) < 0)
                {
                    return (m_lch != null) ? m_lch.FindIndex(value) : 0;
                }
                else if (value.CompareTo(m_value) > 0)
                {
                    return (m_rch != null) ? m_rch.FindIndex(value) + L + 1 : L + 1;
                }
                else
                {
                    return L;
                }
            }

            public T this[int i]
            {
                get
                {
                    int L = Count(m_lch);
                    if (i < L)
                    {
                        return m_lch[i];
                    }
                    else if (i > L)
                    {
                        return m_rch[i - L - 1];
                    }
                    else
                    {
                        return m_value;
                    }
                }
            }
        }

        private Node node;

        public int Count { get; private set; }

        public void Insert(T value)
        {
            if (node != null)
            {
                int k = node.FindIndex(value);
                var pair = Node.Split(node, k);
                node = Node.Merge(Node.Merge(pair.Item1, new Node(value)), pair.Item2);
            }
            else
            {
                node = new Node(value);
            }
            ++Count;
        }

        public int FindIndex(T value)
        {
            return node.FindIndex(value);
        }

        public T this[int i]
        {
            get
            {
                return node[i];
            }
        }
    }

    static long Solve(string S, string T)
    {
        var lists = new Treap<int>[26];
        for (int i = 0; i < 26; ++i)
        {
            lists[i] = new Treap<int>();
        }
        for (int i = 0; i < S.Length; ++i)
        {
            lists[S[i] - 'a'].Insert(i);
        }
        int a = 0, b = 0;
        foreach (char t in T)
        {
            int i = t - 'a';
            if (lists[i].Count == 0) { return -1; }
            int j = lists[i].FindIndex(b);
            if (j < lists[i].Count)
            {
                b = lists[i][j];
            }
            else
            {
                b = lists[i][0];
                ++a;
            }
        }
        return Math.BigMul(S.Length, a) + b + 1;
    }

    static void Main(string[] args)
    {
        string S = Console.ReadLine();
        string T = Console.ReadLine();
        Console.WriteLine(Solve(S, T));
    }
}