Title description
The first line of Description
Input
: contains an integer N.
The second line: contains a string of length N, the string contains only lowercase letters.
The third line: contains a string of length N, the string contains only lowercase letters.
The output
output answer contains only a number L, which represents the maximum possible number of grids in the ring.
Sample Input
input 1:
5
abcdx
cdabz
Input 2:
4
abcd
cdab
Sample Output
output 1:
4
Output 2:
4
Data Constraint
For 20% of the data, 1 <= N <= 5,000
For 50% of the data, 1 <= N <= 600,000
For 100% of the data, 1 <= N <= 2,000,000
answer
exkmp naked question (the
question requires the largest i, so that a[1...i] and b[1...i] are cyclically isomorphic
to find the next array for both strings, enum i, only nextb[j] exists When +1>=i (j=2~nexta[i]+1), (i-1)+(j-1) will be counted in the answer.
Consider the reversed enumeration i. At the same time, it is legal to maintain monotonously with a tree array And the largest j, so that O(n log n) can pass
or enumerate i in positive order. At the same time, the illegal j is deleted (combined with the previous one) with the union check set, and the search is in the union check set. Look up above, this is O(nα(n)).
As for judging methods like nextb[next[a]+1]>i, please leave a comment in the comments if you have proof
code
O(n log n)
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define low(x) (x&-(x))
using namespace std;
struct type{
int x,s;
} b[2000001];
int S[2000001];
int T[2000001];
int f[2000001];
int g[2000001];
int F[2000001];
int G[2000001];
int tr[2000001];
int N,n,i,j,k,l,a,p,L,ans,s;
char st[4000011];
char *Ch=st;
char ch;
bool cmp(type a,type b)
{
return a.x>b.x;
}
void swap(int &x,int &y)
{
int z=x;
x=y;
y=z;
}
int Get()
{
while (*Ch<'a' || *Ch>'z')
*++Ch;
return (*Ch++)-'a';
}
void change(int t,int s)
{
while (t<=n)
{
tr[t]=max(tr[t],s);
t+=low(t);
}
}
int find(int t)
{
int ans=0;
while (t)
{
ans=max(ans,tr[t]);
t-=low(t);
}
return ans;
}
int main()
{
// freopen("beyond1.in","r",stdin);
// freopen("3648.in","r",stdin);
scanf("%d",&n);
fread(st,1,4000011,stdin);
fo(i,1,n)
S[i]=Get();
fo(i,1,n)
T[i]=Get();
// ---
j=1;
while (2+j-1<=n && T[j]==T[2+j-1])
++j;
--j;
g[2]=j;
a=2;
p=2+j-1;
fo(i,3,n)
if (T[1]==T[i])
{
L=g[i-a+1];
if (i+L-1<p)
g[i]=L;
else
{
j=max(p-i+2,2);
while (i+j-1<=n && T[j]==T[i+j-1])
++j;
--j;
g[i]=j;
a=i;
p=i+j-1;
}
}
// ---
j=1;
while (1+j-1<=n && T[j]==S[1+j-1])
++j;
--j;
f[1]=j;
a=1;
p=1+j-1;
fo(i,2,n)
if (T[1]==S[i])
{
L=g[i-a+1];
if (i+L-1<p)
f[i]=L;
else
{
j=max(p-i+2,2);
while (i+j-1<=n && T[j]==S[i+j-1])
++j;
--j;
f[i]=j;
a=i;
p=i+j-1;
}
}
// ------
fo(i,1,n)
swap(S[i],T[i]);
j=1;
while (2+j-1<=n && T[j]==T[2+j-1])
++j;
--j;
G[2]=j;
a=2;
p=2+j-1;
fo(i,3,n)
if (T[1]==T[i])
{
L=G[i-a+1];
if (i+L-1<p)
G[i]=L;
else
{
j=max(p-i+2,2);
while (i+j-1<=n && T[j]==T[i+j-1])
++j;
--j;
G[i]=j;
a=i;
p=i+j-1;
}
}
// ---
j=1;
while (1+j-1<=n && T[j]==S[1+j-1])
++j;
--j;
F[1]=j;
a=1;
p=1+j-1;
fo(i,2,n)
if (T[1]==S[i])
{
L=G[i-a+1];
if (i+L-1<p)
F[i]=L;
else
{
j=max(p-i+2,2);
while (i+j-1<=n && T[j]==S[i+j-1])
++j;
--j;
F[i]=j;
a=i;
p=i+j-1;
}
}
// ------
ans=f[1];
fo(i,2,n)
if (F[i])
{
++N;
b[N].x=F[i];
b[N].s=i;
}
sort(b+1,b+N+1,cmp);
j=1;
fd(i,n,2)
if (f[i])
{
while (j<=N && b[j].x+1>=i)
{
change(b[j].s,b[j].s);
++j;
}
s=find(f[i]+1);
if (s)
ans=max(ans,s+(i-1)-1);
}
printf("%d\n",ans);
}