This article can use the catalog feature yo ↑ (click above [+])
Topic set Link →POJ monthly--2006.03.26
POJ 2774 Long long Message
accept:0 submit:0
Time limit:4000 MS Memory limit:131072 K problem Description
The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days:his mother is getting ill. Being worried about spending so much in railway tickets (Byterland is such a big country, and he have to spend all shours on Train to him hometown), he decided only to send SMS with his mother.
The little cat lives in a Unrich family, so he frequently comes to the Mobile service center, to check how much money he Have spent on SMS.
Yesterday, the computer of service center was broken, and printed, very long messages. The brilliant little cat soon found out:
1. All characters in messages is lowercase Latin letters, without punctuations and spaces.
2. All SMS have been appended other– (i+1)-th SMS comes directly after the i-th one–that are why those Es is quite long.
3. His own SMS have been appended together, but possibly a great many redundancy characters appear leftwards and rightwards Due to the broken computer.
E.g:if his SMS was "motheriloveyou", either long message printed by, the would possibly be one of "Hahamotherilov Eyou "," motheriloveyoureally "," Motheriloveyouornot "," bbbmotheriloveyouaaa ", etc.
4. For these broken issues, the little cat have printed his original text twice (so there appears, very long messages). Even though the original text remains the same in both printed messages, the redundancy characters on both sides would is P Ossibly different.
You are given those-very long messages, and you had to output the length of the longest possible original text Writte n by the little cat.
Background:
The SMS in Byterland Mobile service is charging in Dollars-per-byte. That's why the little cat was worrying about how long could the longest original text being.
Why do I ask you to write a program? There is four resions:
1. The little cat is so busy these days with physics lessons;
2. The little cat wants to keep what he said to his mother Seceret;
3. POJ is such a great Online Judge;
4. The little cat wants to earn some money from POJ, and try to persuade he mother to see the Doctor:(
Input
The strings with lowercase letters on the input lines individually. Number of characters in each one would never exceed 100000.
Output
A number–what is the maximum length of the original text written by the little cat.
Sample Input Yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
Yeaphowmuchiloveyoumydearmother Sample Output problem idea
Problem Solving Ideas:
Test instructions
The topic is a lot of wordy, rather than directly look at the sample
is to give you two strings, the longest common substring of two strings
For example, the longest common substring in the sample is "Howmuchiloveyoumydearmother"
Type
suffix array [longest common substring]
Analysis
This question is a bare suffix array problem.
"Longest common substring" solution (from the National training Team thesis of Ro):
Any substring of a string is prefixed with a suffix of the string. The longest common substring of a and B is equivalent to the maximum value of the longest common prefix for the suffix of a and B. If enumeration a
and b are all suffixes, then this is obviously inefficient. Because the suffix of a and the longest common prefix of the suffix of B are computed, the second string is written after the first string, separated by a character that does not appear, and the suffix array of the new string is then asked. Look and see if you can find some regularity in the suffix array of this new string. Take a= "Aaaba", b= "Abaa" as an example, as shown in the figure.
So is the maximum value of all height values the answer. Not necessarily. It is possible that the two suffixes are in the same string, so height[i] is only satisfied if suffix (sa[i-1]) and suffix (sa[i]) are not two suffixes in the same string. And the biggest of these is the answer. The lengths of the string A and string B are respectively | A| and | b|. The time of the suffix array and the height array for the novelty string is O (| a|+| b|), and then the maximum value of the height value of the two suffixes that are adjacent but originally not in the same string, the time is also O (| a|+| b|), so the time complexity of the entire procedure is O (| a|+| b|). Time complexity has been taken to the lower limit, it is seen that this is a very good algorithm.
PS: Because the two characters match into one character, the middle (position K) is separated by a character that does not appear, so it is possible to determine whether the two suffix is the same string.
That is, when (sa[i]-k) * (sa[i-1]-k) <0, two suffixes belong to a different string, the product may explode when the problem of int, note that you can
"Time Complexity && optimization"
O (NLOGN)
Topic link →POJ 2774 long long Message Source Code
/*sherlock and Watson and adler*/#pragma comment (linker, "/stack:1024000000,1024000000") #include <stdio.h> # include<string.h> #include <stdlib.h> #include <queue> #include <stack> #include <math.h > #include <vector> #include <map> #include <set> #include <bitset> #include <cmath> # include<complex> #include <string> #include <algorithm> #include <iostream> #define EPS 1e-9 #
Define LL Long Long #define PI ACOs ( -1.0) #define BITNUM (a) __builtin_popcount (a) using namespace Std;
const int N = 10;
const int M = 100005;
const int inf = 1000000007;
const int mod = 1000000007;
const int MAXN = 200005; Rnk starting from 0//sa starting from 1, because the last character (the smallest) is ranked No. 0 bit//height starting from 1, because it represents sa[i-1] and sa[i]//Multiplication algorithm O (nlogn) int WA[MAXN], WB[MAXN], WV[MAXN
], WS_[MAXN]; The parameter m of the suffix function represents the range of characters in the string, is a parameter of the radix sort, if the original sequence is a letter can be directly taken 128, if the original sequence itself is an integer, then M can take the largest integer greater than 1 of the value//string to be sorted in the R array, from r[0] to r[ N-1], length n//To facilitate the comparison of the size, you can add a character after the string, the character does not appear in the preceding characters, and is smaller than the preceding characters//Ibid, for function operation, the Convention except r[n-1] all R[i] is greater than 0,r[n-1]=0//function ends, the result is placed in the SA array, from sa[0] to sa[n-1] void Suffix (int *r, int *sa, int n, int m) {int I
, J, k, *x = WA, *y = WB, *t; Sort a string of length 1//In general, the maximum value of R is not very large in the string's title, so the radix sort is used here//if the maximum value of R is large, then the code is changed to quick sort for (i = 0; i < m; ++i) Ws_[i]
= 0;
for (i = 0; i < n; ++i) Ws_[x[i] = r[i]]++;//The number of statistical characters for (i = 1; i < m; ++i) ws_[i] + = ws_[i-1];//statistics not greater than the number of characters I for (i = n-1; I >= 0; i) sa[--ws_[x[i]] = i;//calculated character Rank//radix sort//x array holds the value equivalent to the rank value for (j = 1, k = 1; k < n; J *= 2, M = k) {//j is the length of the current string, array y holds the result of ordering the second keyword//second keyword sort for (k = 0, i = n-j; i < n; ++i ) y[k++] = i;//The second keyword is 0 of the row in front for (i = 0; i < n; ++i) if (Sa[i] >= j) y[k++] = sa[i]-j;//"Length of J substring Sa[i] should be 2 * J Substring Sa[i]-j suffix (second keyword), for all substrings of length 2 * j are sorted according to the second keyword for (i = 0; i < n; ++i) Wv[i] = x[y[i]];//Extract First keyword//press
The First keyword sort (principle is the same as the string of length 1) for (i = 0; i < m; ++i) ws_[i] = 0; for (i = 0; I &lT N
++i) ws_[wv[i]]++;
for (i = 1; i < m; ++i) ws_[i] + = ws_[i-1]; for (i = n-1; I >= 0; i) sa[--ws_[wv[i]] = y[i];//The number of substrings ranked 2 * j is calculated by the first keyword//At this point the array x is the rank of a substring of length J, and the array y is still based on the second
The result of the keyword sorting//the rank of the substring with a length of 2 * j, saved to array x t = x;
x = y;
y = t; For (x[sa[0]] = 0, i = k = 1; i < n; ++i) x[sa[i] = (Y[sa[i-1] [= Y[sa[i]] && Y[sa[i-1] + j] = = Y[sa[i] + j])?
K-1: k++;
If the substring of length 2 * j Sa[i] is exactly the same as sa[i-1], then they have the same rank}} int RANK[MAXN], HEIGHT[MAXN], SA[MAXN], R[MAXN];
void calheight (int *r,int *sa,int n) {int i,j,k=0;
for (I=1; i<=n; i++) rank[sa[i]]=i;
For (i=0, i<n; height[rank[i++]]=k) for (k?k--:0,j=sa[rank[i]-1]; r[i+k]==r[j+k]; k++);
} Char S[MAXN];
int main () {int k,n,i,max;
while (~SCANF ("%s", s)) {max=0;
K=strlen (s);
S[k]= ' z ' +1;
scanf ("%s", s+k+1);
N=strlen (s); for (i=0;i<n;i++) r[i]=s[i]-' a ' +1;
r[i]=0;
Suffix (r,sa,n+1,28);
Calheight (R,sa,n); for (i=1;i<=n;i++) if (height[i]>max&&1ll* (sa[i]-k) * (sa[i-1]-k) <0) max=height[i
];
printf ("%d\n", Max);
} return 0; }
Rookie growth notes