文字列$t$と$t$の部分文字列$p$,文字列$t$のどの文字を消していくかのindexが与えられる.部分文字列$p$が得られなくなるため,文字を消していく作業を続ける時に,最大で何個消せるか.
一文字ずつ順番に消していき,その文字列が$p$を構成できるかどうか(連続している必要はない)を試すのには$O(n ^2)$なので間に合わない.配列を$p$を構成できるかできないか,を$yes / no$で持った時に,$[yes, yes, …, yes, no, …, no]$になるので,この$yes$の右端を二分探索で求める.二分探索で今見ている番目まで文字列を消し,$p$を構成できるかを見るので$O(n logn)$となる.
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,k,n) for(int i=k;i<(int)(n);i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define INF 1<<30
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
bool used[200005];
int main() {
string s, t;
cin >> s >> t;
vector<int> a(s.size());
rep(i, s.size()) {
cin >> a[i];
a[i]--;
}
int l = -1, r = s.size() + 5;
while(r - l > 1) {
int med = (l + r) / 2;
memset(used, 0, sizeof(used));
rep(i, med) {
used[a[i]] = true;
}
string ss = "";
rep(i, s.size()) {
if(used[i]) continue;
else ss += s[i];
}
bool flag = true;
int tid = 0;
rep(i, ss.size()) {
if(ss[i] == t[tid]) {
tid++;
}
}
if(tid == t.size()) l = med;
else r = med;
}
cout << r - 1 << endl;
return 0;
}