CF1138D(545,div2) Camp Schedule

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');

}

 

Guess you like

Origin www.cnblogs.com/sahdsg/p/12299013.html