[Ybt Advanced 2-3-2] Repeat substring

Repeat substring

Topic link: ybt efficient advanced 2-3-2

Topic

Given several strings, ask each string at most how many identical substrings are repeatedly concatenated.

Ideas

For this question, we consider using KMP, first run KMP on this string.

f a i l n fail_n failnIt means 1 ∼ failn 1\sim fail_n1failnSubstring of n − failn + 1 ∼ n n-fail_n+1\sim nnfailn+1The substrings of n are equal.

Then we consider under what circumstances will it consist of multiple identical substrings.
Let's draw a picture to see:
Insert picture description here
this is a number, not a string, we just have to assume the positions of equal substrings.

If you want to become two paragraphs, it must be separated from the middle. (As shown in the figure below)
Insert picture description here
If you want to divide it into three sections, you have to divide it three times, but you can only separate from one place.
When we consider where to separate, it is equivalent to third-class separation.
Insert picture description here
Then we need s 1 ∼ 4 = s 5 ∼ 8 = s 9 ∼ 12 s_{1\sim4}=s_{5\sim8}=s_{9\sim12}s14=s58=s912.
Then think about the two parts divided into 1 ∼ a 1\sim a1a sumn − a + 1 ~ n n-a + 1 \ sim nna+1n , that is less than or equal toaaa positive integerbbb , there will be1 ∼ b 1\sim b1b sumn − a + 1 ~ n − a + b n-a + 1 \ sim n-a + bna+1na+b is equal.
In fact, if there is another one greater than or equal tobbb , less than or equal toaaa positive integerccc , there will beb ∼ cb\sim cbc n − a + b ∼ n − a + c n-a+b\sim n-a+c na+bna+c

Then we can find that we let the length be 8 88 is fine!
There are four that intersect, and then the first four and the last four of the two that are separated are equal, which is exactly what we want.

What if it is divided into four sections?
It’s not hard to think that the length is 9 99

To summarize the law, when the sequence length is nnn , you have to divide it intoxxx 段时, f a i l n fail_n failnIt should be n − nx n-\dfrac{n}{x}nxn.
(Of course, nnn must bexxThe multiple of x , otherwise it will be indistinguishable)

Let's take a look when failn fail_nfailnWhen it has been determined, it should be divided into several sections.
That is nn − failn \dfrac{n}{n-fail_n}nfailnn, The shift item is available.
Of course, you can also know, the premise is nnn n − f a i l n n-fail_n nfailnMultiples of, otherwise it can only be divided into one. (Just one whole)

Code

#include<cstdio>
#include<cstring>

using namespace std;

int an, ans, fail[1000001], j;
char a[1000001];

int main() {
    
    
	scanf("%s", a + 1);
	an = strlen(a + 1);
	
	while (an != 1 || a[1] != '.') {
    
    //KMP
		j = 0;
		for (int i = 2; i <= an; i++) {
    
    
			while (j && a[i] != a[j + 1]) j = fail[j];
			if (a[i] == a[j + 1]) j++;
			fail[i] = j;
		}
		
		if (an % (an - fail[an]) == 0) printf("%d\n", an / (an - fail[an]));//可以分段
			else printf("1\n");//分不了段,就只能一整个
		
		scanf("%s", a + 1);
		an = strlen(a + 1);
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/112976869