jzoj3648. 【GDOI2014】beyond

Title description

The first line of Description
Insert picture description here
Insert picture description here
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);
}

Guess you like

Origin blog.csdn.net/gmh77/article/details/99240613