[Jsoi2016] Twist the palindrome string

Source: Internet
Author: User

Description

The JYY has two strings A and b with a length of N.
A "twist string s (i,j,k) substring consisting of the I character in A to the first J character
Concatenation with a substring of the J character in B to the K-character.
For example, if a= ' XYZ ', b= ' UVW ', then twist the string s (#) = ' XYVW '.
Jyy defines a "twisted palindrome" for one of the following situations:
A palindrome string in the 1.A;
A palindrome string in the 2.B;
3. Or a palindrome twist string s (i,j,k)
Now Jyy want to find the longest twist palindrome.

Input

The first line consists of a positive integer n.
The second line contains an uppercase string A with a length of N.
The third line contains a string B with a length of N, consisting of uppercase letters.
1≤n≤10^5

Output

The first line of the output is an integer that represents the longest twisting palindrome string.

Sample Input
5
ABCDE
Baecb

Sample Output
5

HINT
The twist palindrome in the best scenario is shown below (the characters in the palindrome are not used.):
. Bc..
.. ECB

First, we need to know two things about the twisted palindrome.
1, it is a string or string B substring
2, its symmetry center has a part in a string or B string

For the first situation is very good to write, there is no more to say, mainly to talk about the second situation

For the second case, we first enumerate the palindrome string midpoint I, and then find the maximum expansion of the maximum range (I-p[i]~i+p[i]), if the palindrome string in the midpoint of a string, then a string can continue to fetch the range is (1~i-p[i]-1), and B string can be taken in the range is (i+p[i]~ Len), if the center point is similar in string B.

So what do we do next? Two-minute length. A length of two, and then judge whether part of a is the same as a part of B string

How to judge? Hash. Record the hash out of the value of the prefix and the B string record suffix and, judging by the time do similar prefixes and subtraction can, remember double hash

Still don't understand? On the Code

#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include < Algorithm> #define INF 0x7f7f7f7fusing namespace std;typedef long long ll;typedef unsigned int ui;typedef unsigned long    Long Ull;inline int read () {int X=0,f=1;char ch=getchar (); for (;ch< ' 0 ' | |    Ch> ' 9 '; Ch=getchar ()) if (ch== '-') f=-1;    for (; ch>= ' 0 ' &&ch<= ' 9 '; Ch=getchar ()) x= (x<<1) + (x<<3) +ch-' 0 '; return x*f;}    inline void print (int x) {if (x>=10) print (X/10); Putchar (x%10+ ' 0 ');} const int N=1e5,limit=27,p1=100007,p2=233333;char a[n*2+10],b[n*2+10];int Pa[n*2+10],pb[n*2+10];int sumA[2][N*2+10]    , Sumb[2][n*2+10],g[2][n*2+10];int len,ans;void work (char *s,int *p) {int max=0,id=0;        for (int i=1;i<=len;i++) {p[i]=max>i?min (p[id*2-i],max-i): 1;        while (S[i+p[i]]==s[i-p[i]]) p[i]++;    if (max<p[i]+i) max=p[id=i]+i; }}bool Check (int l1,int r1,int l2,int r2,int Len) {//hash judgment, using prefix and int x= (SUMA[0][R1]-1LL*SUMA[0][L1-1]*G[0][LEN]%P1)%p1;    int y= (SUMB[0][L2]-1LL*SUMB[0][R2+1]*G[0][LEN]%P1)%p1;    x= (X+P1)%p1,y= (Y+P1)%p1;    if (x!=y) return 0;    x= (SUMA[1][R1]-1LL*SUMA[1][L1-1]*G[1][LEN]%P2)%p2;    Y= (SUMB[1][L2]-1LL*SUMB[1][R2+1]*G[1][LEN]%P2)%p2;    x= (X+P2)%p2,y= (Y+P2)%p2; return x==y;}    int solve (int j,int k) {//two min enumeration length int l=0,r=min (j, (Len>>1)-k+1), ans=0;        while (l<=r) {int mid= (L+R) >>1;        if (check (j-mid+1,j,k,k+mid-1,mid)) L=mid+1,ans=mid;    else r=mid-1; } return ans;    int main () {len=read ();    scanf ("%s%s", a+1,b+1);    for (int i=len;i;i--) a[i<<1]=a[i],b[i<<1]=b[i],a[i<<1|1]=b[i<<1|1]= ' & ';    len=len<<1|1;    a[0]=b[0]= ' # ', a[1]=b[1]= ' & ', a[len+1]=b[len+1]= ' ^ ', g[0][0]=g[1][0]=1;    Work (A,PA), work (B,PB);  for (int i=1;i<=len;i++) pa[i]--, pb[i]--; Palindrome string length will be more than one, should be subtracted for (int i=1;i<=len;i++) Ans=max (Ans,max (Pa[i],pb[i])),//palindrome string for the case of a substring g[0][i]=1ll* g[0][i-1]*LIMIT%P1, G[1][I]=1LL*G[1][I-1]*LIMIT%P2;        Record something like the binary for (int i=2;i<len;i+=2) suma[0][i>>1]= (1ll*suma[0][(i>>1) -1]*limit+a[i])%P1,  Suma[1][i>>1]= (1ll*suma[1][(i>>1) -1]*limit+a[i])%p2; Record two hash prefixes and one extra bit at a time to multiply the last binary (limit) for (int i=len-1;i>1;i-=2) sumb[0][i>>1]= (1ll*sumb[0][(i>>1) +1]  *limit+b[i])%p1, sumb[1][i>>1]= (1ll*sumb[1][(i>>1) +1]*limit+b[i])%p2;        Because of symmetry, so the record of B string to start from the back for (int i=2;i<len;i++) {//Palindrome center in the case of a string int l=i-pa[i],r=i+pa[i];        L= (l+1) >>1,r>>=1;    Ans=max (Ans,pa[i]+solve (l-1,r));        } for (int i=2;i<len;i++) {//palindrome string Center in B string case int l=i-pb[i],r=i+pb[i];        L= (l+1) >>1,r>>=1;    Ans=max (Ans,pb[i]+solve (l,r+1));    } printf ("%d\n", Ans); return 0;}

[Jsoi2016] Twist the palindrome string

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.