CF1137B
考虑利用 $\text{KMP}$ 辅助进行贪心。
先预处理出 $t$ 所有前缀的 $\text{border}$,也就是熟知的 $next$ 数组。然后在 $s$ 上做一个贪心的匹配——假若 $s$ 剩余的字符中还存在能和 $t$ 中匹配的字符,那必定优先选它;否则之后只有一种可能,就是一直取同样的一个字符。
至于贪心的正确性,可以凭借直觉/归纳反证。
#include <bits/stdc++.h>
#define FL(i, a, b) for(int i = (a); i <= (b); i++)
#define FR(i, a, b) for(int i = (a); i >= (b); i--)
using namespace std;
const int N = 5e5 + 10;
int n, m, j = 1, nxt[N], cnt[N];
char a[N], b[N], ans[N];
void get_nxt(){
int j = 0;
FL(i, 2, m){
while(j && b[j + 1] != b[i]) j = nxt[j];
if(b[j + 1] == b[i]) j++; nxt[i] = j;
}
}
int main(){
scanf("%s%s", a + 1, b + 1);
n = strlen(a + 1), m = strlen(b + 1);
FL(i, 1, n) cnt[a[i]]++; get_nxt();
FL(i, 1, n){
if(cnt[b[j]]) cnt[ans[i] = b[j]]--;
else cnt[ans[i] = (b[j] ^ 1)]--;
if(j == m) j = nxt[j]; j++;
}
printf("%s", ans + 1);
return 0;
}