https://vjudge.net/problem/CodeForces-1138D
topic
There are two strings s and t, including only the characters "0" and "1" s in order to adjust the required characters to maximize the number of times a string appears t.
$1 \leqslant |s| \leqslant 500\,000$,$1 \leqslant |s| \leqslant 500\,000$
answer
kmp template title + greedy ......
kmp algorithm is the longest common prefixes and suffixes for each location, so only need to use the longest common prefixes and suffixes of strings can be a whole
First count the number of each character in s, then t greedy filling shining, if not all the rest of the output, if you jump directly to t filling over the filling to continue after a prefix.
Why is there a maximum number of times? Because once after filling is complete, requires a minimum fill "the entire length of the string - the prefix length" characters, this is certainly not filling other better
Time complexity of O (n)
AC Code
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cctype> #include<cassert> #define REP(i,a,b) for(register int i=(a); i<(b); i++) #define REPE(i,a,b) for(register int i=(a); i<=(b); i++) #define PERE(i,a,b) for(register int i=(a); i>=(b); i--) using namespace std; typedef long long ll; #define MAXN 500007 int f[MAXN]; char s[MAXN], t[MAXN]; inline void getf(char *s, int l) { int t=f[0]=-1; REP(i,0,l) { while(t>=0 && s[i]!=s[t]) t=f[t]; t++; f[i+1]=t; } } int main() { scanf("%s%s", s, t); int ls=strlen(s), lt=strlen(t); int cnt[2]={0,0}; getf(t,lt); REP(i,0,ls) cnt[s[i]-'0']++; int pos=0; while(1) { if(cnt[t[pos]-'0']>0) { putchar(t[pos]); cnt[t[pos]-'0']--; pos++; if(pos==lt) pos=f[pos]; } else break; } while(0<cnt[0]--) putchar('0'); while(0<cnt[1]--) putchar('1'); putchar('\n'); }