Problem:
C： たったひとつの部分列 - Unique Subsequence -

問題

ある日えびちゃんは、机の上に長さ n のテキスト文字列 T と長さ m のパターン文字列 P (m \leq n) が置かれていることに気づきました。えびちゃんは、文字列に現れる「たったひとつの部分列」が大好きであるため、 P が T のたったひとつの部分列であるかどうかをすぐに調査し始めました。

P が T のたったひとつの部分列であるという性質は以下のように表されます。ここで、文字列 X の i 文字目を X_i と書きます。

長さ m の数列 S = (s_1, ..., s_m) (ただし、 s_1 < s_2 < ... < s_m) で、各 i (i = 1, ..., m) について T_{s_i} = P_i である数列 S が一意に定まる。

調査を始めてから数時間、えびちゃんは文字列をぐっと睨んでいましたが、文字列が長すぎるために疲れてしまったようです。それを見かねたあなたは、えびちゃんを手伝ってあげることにしました。えびちゃんのために、 P が T のたったひとつの部分列であるならば “yes” を、そうでないならば “no” を出力するプログラムを作成してください。

入力形式

T
P

1 行目には、テキスト文字列 T が与えられる。
2 行目には、パターン文字列 P が与えられる。

制約

1 \leq |P| \leq |T| \leq 5 \times 10^5

T および P は英字小文字 ‘a’-’z’ で構成される。

出力形式

P が T のたったひとつの部分列であるならば “yes” を、そうでないならば “no” を1行に出力してください。

入力例1

aizucamp
azu

出力例1

yes

入力例2

abracadabra
rada

出力例2

no

入力例3

hokkaido
dekai

出力例3

no

Solution in C++11 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define pb push_back

const string ok = "yes", ng = "no";

string solve()
{
    string t,p;
    cin >>t >>p;
    int T = t.size(), P = p.size();

    vector<int> head,tail;

    // head
    int idx = 0;
    rep(i,T)
    {
        if(idx<P && p[idx]==t[i])
        {
            head.pb(i);
            ++idx;
        }
    }

    // tail
    idx = P-1;
    for(int i=T-1; i>=0; --i)
    {
        if(idx>=0 && p[idx]==t[i])
        {
            tail.pb(i);
            --idx;
        }
    }
    reverse(tail.begin(),tail.end());

    if(P != head.size() || head.size() != tail.size()) return ng;

    rep(i,P)if(head[i]!=tail[i]) return ng;

    return ok;
}

int main()
{
    cout << solve() << endl;
    return 0;
}