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 Rust (1.42.0) (judge verdict: Accepted)

#![allow(non_snake_case)]
#![allow(unused_imports)]
use ascii::AsciiChar;
use ascii::AsciiStr;
use itertools::Itertools as _;
use permutohedron::LexicalPermutation as _;
use petgraph::algo::dijkstra;
use petgraph::algo::min_spanning_tree;
use petgraph::data::FromElements;
use petgraph::graph::NodeIndex;
use petgraph::graph::UnGraph;
use petgraph::unionfind::UnionFind;
use proconio::fastout;
use proconio::input;
use proconio::marker::Chars;
use proconio::marker::Usize1;
use std::cmp::max;
use std::cmp::min;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::VecDeque;
use superslice::Ext as _;

#[fastout]
fn main() {
    input! {
        S: Chars,
        T: Chars,
    }

    let s_char_set: HashSet<char> = S.clone().into_iter().collect();
    let t_char_set: HashSet<char> = T.clone().into_iter().collect();

    if !s_char_set.is_superset(&t_char_set) {
        println!("-1");
        return;
    }

    // どの文字が何ind目にあるか
    let mut char_to_ind: HashMap<char, Vec<usize>> = HashMap::new();
    for ind in 0..S.len() {
        let c = S[ind];
        if char_to_ind.contains_key(&c) {
            let orig = char_to_ind.get_mut(&c).unwrap();
            orig.push(ind);
        } else {
            let v = vec![ind];
            char_to_ind.insert(c, v);
        }
    }

    // "contest"
    // t [3, 6]
    // e [4]
    // c [0]
    // s [5]
    // o [1]
    // n [2]
    // for (k, v) in char_to_ind.iter() {
    //     eprintln!("{} {:?}", k, v);
    // }

    // しゃくとり法を厳密に理解していないので違うかもしれないが、
    // しゃくとり法のように2つの配列のindexを持って動かしていけばいけそう

    // 何個目のSか?(0-origin)
    // すなわち、何個のSを見終わったか?
    let mut s_nth: usize = 0;

    // Sの中で、次は何文字目から見始めるか
    let mut local_s_ind: usize = 0;

    // char_to_indのどこを見ているか
    // 次のSに進んだ時に初期化できるように、これは残しておく
    let initial_char_ind_mp: HashMap<char, usize> = {
        let mut mp: HashMap<char, usize> = HashMap::new();

        for (&c, _) in char_to_ind.iter() {
            mp.insert(c, 0);
        }
        mp
    };

    let mut char_ind_mp = initial_char_ind_mp.clone();

    for t_ind in 0..T.len() {
        let t_ch = T[t_ind];
        dbg!(t_ch);

        let ind_vec: &Vec<usize> = char_to_ind.get(&t_ch).unwrap();

        let char_ind_ref: &mut usize = char_ind_mp.get_mut(&t_ch).unwrap();

        if local_s_ind <= ind_vec[*char_ind_ref] {
            // let tmp = local_s_ind;
            local_s_ind = ind_vec[*char_ind_ref] + 1;
        // eprintln!("1: {} -> {}", tmp, local_s_ind);
        } else if *char_ind_ref < ind_vec.len() - 1 {
            while !(local_s_ind <= ind_vec[*char_ind_ref]) && *char_ind_ref < ind_vec.len() - 1 {
                *char_ind_ref += 1;
            }

            // whileを抜けたということは、条件を満たしたか、末尾に達したかのどちらか
            if local_s_ind <= ind_vec[*char_ind_ref] {
                // let tmp = local_s_ind;
                local_s_ind = ind_vec[*char_ind_ref] + 1;
            // eprintln!("2: {} -> {}", tmp, local_s_ind);
            } else {
                // sを次の文字セットへ
                s_nth += 1;
                local_s_ind = ind_vec[0] + 1;
                char_ind_mp = initial_char_ind_mp.clone();
            }
        } else {
            // sを次の文字セットへ
            s_nth += 1;
            local_s_ind = ind_vec[0] + 1;
            char_ind_mp = initial_char_ind_mp.clone();
        }
    }

    // 途中まで見てた状態でループを抜けているので、
    // それを踏まえて答えを算出
    // local_s_indは「次に見るべき位置」を指しているので、1を引く
    // 0-originインデックスから1-originに戻すために+1
    let ans = S.len() * s_nth + (local_s_ind - 1) + 1;

    println!("{}", ans);
}