文字列$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;
}