https://vjudge.net/problem/CodeForces-1138D
タイトル
文字列がトンを出現する回数を最大化するために必要な文字を調整するために、そこだけ文字を含む二つの文字列sとtは、「0」と「1」の。
$ 1 \ leqslant | S | \ leqslant 500 \、000 $、$ 1 \ leqslant |よ| \ leqslant 500 \、000 $
問題の解決策
KMPテンプレートのタイトル+貪欲......
KMPアルゴリズムはこれだけ全体をすることができ、文字列の最長共通接頭辞と接尾辞を使用する必要があり、それぞれの場所のため、最長共通接頭辞と接尾辞であります
まず、s内の各文字の数をカウントあなたは接頭辞の後に継続して充填の上にトン充填に直接ジャンプすると、その後、出力の全てではないに残り、輝く貪欲充填のt。
なぜ倍の最大数はありますか?充填が完了した後、「文字列の全体の長さ - プレフィックス長」最小充填を必要としたらので文字が、これは他のより良いを埋める確かではありません
Oの時間複雑度(N)
ACコード
#include <cstdioを> する#include <CStringの> する#include <アルゴリズム> の#include <キュー> の#include <CCTYPE> の#include <cassert> の#define REP(I、B)のための(レジスタINT I =(); I <(B)、I ++) の#define REPE(I、B)(登録INT I =(用); I <=(B); I ++) の#defineペール(I、B)のための(レジスタINT iは()=; I> =(B); i--) 名前空間stdを使用。 長い長いLLのtypedef。 #define MAXN 500007 int型F [MAXN]。 チャーS [MAXN]、T [MAXN]。 インラインボイドGETF(CHAR * S、INT 1){ int型、T = F [0] = - 1。 REP(I、0、L){ ながら(!T> = 0 && S [I] = S [T])T = [T] F。 トン++; 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; 一方、(1){ IF(CNT [T [POS] - '0']> 0){ のputchar(T [POS])。 CNT [T [POS] - '0'] - 。 POS ++; IF(POS == LT)POS = [POS] F。 }他にブレーク。 } ながら(0 <CNT [0] - )のputchar( '0')。 一方、(0 <CNT [1] - )のputchar( '1')。 putchar( '\ n'は); }