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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
// おまじない
#define INCANT cin.tie(0), cout.tie(0), ios::sync_with_stdio(false), cout << fixed << setprecision(20);
#define int long long
// alias
#define gcd __gcd
#define pb push_back
#define all(x) (x).begin(), (x).end()
template<typename T>
bool chmax(T& a, T b){return (a = max(a, b)) == b;}
template<typename T>
bool chmin(T& a, T b){return (a = min(a, b)) == b;}
template<class T>
int lb(vector<T>& x,T n){return lower_bound(all(x) , n) - x.begin();}
template<class T>
int ub(vector<T>& x,T n){return upper_bound(all(x) , n) - x.begin();}
// for
#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(...) _overload(__VA_ARGS__, repi, _rep)(__VA_ARGS__)
#define _rev(i, n) revi(i, n, 0)
#define revi(i, a, b) for(int i = (int)(a - 1); i >= (int)(b); i--)
#define rev(...) _overload(__VA_ARGS__, revi, _rev)(__VA_ARGS__)
#define each(i, n) for(auto&& i: n)
// 入力
void in(){}
template<typename F, typename... R>
bool in(F& f, R&... r){
    if(cin >> f){in(r...);return true;}
    else return false;
}
// 出力
#define out(x) cout << (x)
#define space() cout << " "
#define indent() cout << '\n'
void print(){}
template<typename F, typename... R>
void print(F f, R... r){out(f), indent(), print(r...);}
// デバッグ出力
#define debughead(x) cerr << "Line " << __LINE__ << ": " << #x << ": "
#define debugout(x) cerr << (x) << " "
#define debugindent() cerr << '\n'
#define debug(x) debughead(x), debugout(x), debugindent()
// 脳死
#define YN(x) out((x) ? "YES" : "NO"), indent()
#define Yn(x) out((x) ? "Yes" : "No"), indent()
#define yn(x) out((x) ? "yes" : "no"), indent()
// const
int INF = 1e18, MOD = 1e9 + 7;
double EPS = 1e-15, PI = acos(-1);
int dx[] = {0, 0, 1, 0, -1, -1, 1, 1, -1}, dy[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
// 数学的な
int lcm(int a, int b){return a / gcd(a, b) * b;}
int factorial(int a){return a < 2 ? 1 : factorial(a - 1) * a;}
int summation(int a){return a < 1 ? 0 : (a * a + a) / 2;}
int combination(int n, int r){ int res = 1; rep(i, 1, r + 1){ res *= n--, res /= i; } return res; }
bool isPrime(int n){ rep(i, 2, sqrt(n) + 1){ if(i > 3){ i++; } if(!(n % i)){ return false; } } return true; }
vector<int> divisor(int n){ vector<int> ans; rep(i, 1, sqrt(n) + 1){ if(!(n % i)){ ans.pb(i); if(i * i < n){ ans.pb(n / i); } } } return ans; }
map<int, int> factorization(int n){ map<int, int> ans; rep(i, 2, sqrt(n) + 1){ if(i > 3){ i++; } while(!(n%i)){ ans[i]++, n /= i; } } if(n > 1){ ans[n]++; } return ans; }
// MOD int
int extgcd(int a, int b, int &x, int &y){ int g = a; x = 1, y = 0; if(b){ g = extgcd(b, a % b, y, x); y -= a / b * x; } return g; }
int invmod(int a, int m = MOD){ int x = 0, y = 0; extgcd(a, m, x, y); return (x + m) % m; }
struct mint{
    int _num;
    mint(int x = 0) : _num(){ _num = x % MOD; if(_num < 0){ _num += MOD; } }
    inline mint operator = (int x){ _num = x % MOD; if(_num < 0){ _num += MOD; } return *this; }
    inline mint operator = (mint x){ _num = x._num; return *this; }
    inline mint operator + (int x){ return mint(_num + x); }
    inline mint operator + (mint x){ int a = _num + x._num; if(a >= MOD){ a -= MOD; } return mint{a}; }
    inline mint operator += (int x){ _num += x; _num %= MOD; if(_num < 0){ _num += MOD; } return *this; }
    inline mint operator += (mint x){ _num += x._num; if(_num >= MOD){ _num -= MOD; } return *this; }
    inline mint operator ++ (){ _num++; if(_num == MOD){ _num = 0; } return *this; }
    inline mint operator - (int x){ return mint(_num - x); }
    inline mint operator - (mint x){ int a = _num - x._num; if(a < 0){ a += MOD; } return mint{a}; }
    inline mint operator -= (int x){ _num -= x; _num %= MOD; if(_num < 0){ _num += MOD; } return *this; }
    inline mint operator -= (mint x){ _num -= x._num; if(_num < 0){ _num += MOD; } return *this; }
    inline mint operator -- (){ _num--; if(_num == -1){ _num = MOD - 1; } return *this; }
    inline mint operator * (int x){ return mint(_num * (x % MOD)); }
    inline mint operator * (mint x){ return mint{_num * x._num % MOD}; }
    inline mint operator *= (int x){ _num *= mint(x); _num %= MOD; return *this; }
    inline mint operator *= (mint x){ _num *= x._num; _num %= MOD; return *this; }
    inline mint operator / (int x){ return mint(_num * invmod(mint(x), MOD)); }
    inline mint operator / (mint x){ return mint{_num * invmod(x._num, MOD) % MOD}; }
    inline mint operator /= (int x){ _num *= invmod(mint(x), MOD); _num %= MOD; return *this; }
    inline mint operator /= (mint x){ _num *= invmod(x._num, MOD); _num %= MOD; return *this; }
    inline mint pow(int x){ mint ans = 1, cnt = *this; for(int i = 1; i < x + 1; i *= 2){ if(x & i){ ans *= cnt; x ^= i; } cnt *= cnt; } return ans; }
    inline operator int() { return _num; }
};
vector<mint> fac(1, 1), inv(1, 1);
void reserve(int a){
    if(fac.size() >= a) return;
    if(a < fac.size() * 2) a = fac.size() * 2;
    if(a >= MOD) a = MOD;
    while(fac.size() < a) fac.push_back(fac.back() * (int)(fac.size()));
    inv.resize(fac.size());
    inv.back() = mint(1) / fac.back();
    for(int i = inv.size() - 1; !inv[i - 1]; i--) inv[i - 1] = inv[i] * i;
}
mint fact(int n){ if(n < 0) return 0; reserve(n + 1); return fac[n]; }
mint perm(int n, int r){ if(r < 0 || n < r) return 0; reserve(n + 1); return fac[n] * inv[n - r]; }
mint comb(int n, int r){ if(r < 0 || n < r) return 0; reserve(n + 1); return fac[n] * inv[r] * inv[n - r]; }
mint mcomb(int n, int r){ return comb(n + r - 1, n - 1); } // r個をn部屋に分ける
// UnionFind
struct UF{
    vector<int> t;
    UF(int size): t(size, -1){}
    int root(int x){return t[x] < 0 ? x : t[x] = root(t[x]);}
    int size(int x){return -t[root(x)];}
    bool isSame(int x, int y){return root(x) == root(y);}
    bool unite(int x, int y){
        x = root(x), y = root(y);
        if(x != y){
            if(t[y] < t[x]){
                swap(x, y);
            }
            t[x] += t[y], t[y] = x;
        }
        return x != y;
    }
};
// main
main(){
    INCANT;
    int n, res = 0, last = 0;
    string s, t;
    in(s, t);
    map<char, bool> flag;
    map<char, vector<int>> syutu;
    rep(i, s.size()){
        char c = s[i];
        syutu[c].pb(i);
        flag[c] = true;
    }

    each(c, t){
        if(!flag[c]){
            print(-1);
            return 0;
        }
    }

    res += syutu[t[0]][0] + 1;
    //debug(res);
    last = syutu[t[0]][0];
    if(t[0] == t[1]) last++, res++;

    rep(i, t.size()){
        if(i == 0){continue;}
        char c = t[i];
        //debug(c);
        if(syutu[c][syutu[c].size() - 1] < last){
            //debug(last);
            res += s.size() - last;
            last = 0;
        }

        int left = 0, right = syutu[c].size(), mid;
        while(abs(left - right) > 1){
            mid = (left + right) / 2;
            //debug(syutu[c][mid]);
            if(syutu[c][mid] > last){
                right = mid;
            }else{
                left = mid;
            }
        }
        //debug(left);
        //debug(right);
        int j = syutu[c][left];
        res += j - last;
        //debug(res);
        last = j;
        if(i != t.size() - 1){
            if(t[i] == t[i + 1]) last++, res++;
        }
    }
    print(res);
}