bzoj3976
题解:
先跑一下Sa
然后再用kmp匹配一下哪一些位置不行
然后二分答案
代码:
#include<bits/stdc++.h>
const int N=;
using namespace std;
int t[N],a[N],xx[N],yy[N],*x,*y,height[N],rank[N],sa[N];
int n,m,len,len1,pd[N],pd1[N],pd2[N],v[N],p,st[][N],L[N];
char s1[N],s2[N],s3[N];
void get_fail()
{
t[]=-; int j;
for (int i=;i<len1;i++)
{
j=t[i];
while (j!=-&&s3[j]!=s3[i]) j=t[j];
t[i+]=++j;
}
}
void kmp(char s[N],int a[N],int l)
{
int i=; int j=;
while (j<=l)
{
if (s3[i]==s[j]||i==-) i++,j++;
else i=t[i];
if (i==len1)
{
a[j-len1]=;
i=t[i];
}
}
}
int cmp(int i,int j,int k)
{
return y[i]==y[j]&&(i+k>len?-:y[i+k])==(j+k>len?-:y[j+k]);
}
void get_sa()
{
x=xx; y=yy; int m1=;
for (int i=;i<=len;i++) v[x[i]=a[i]]++;
for (int i=;i<=m1;i++) v[i]+=v[i-];
for (int i=len;i>=;i--) sa[v[x[i]]--]=i;
for (int k=;k<=len;k<<=)
{
p=;
for (int i=len-k+;i<=len;i++) y[++p]=i;
for (int i=;i<=len;i++)
if (sa[i]>k) y[++p]=sa[i]-k;
for (int i=;i<=m1;i++) v[i]=;
for (int i=;i<=len;i++) v[x[y[i]]]++;
for (int i=;i<=m1;i++) v[i]+=v[i-];
for (int i=len;i>=;i--) sa[v[x[y[i]]]--]=y[i];
swap(x,y); p=; x[sa[]]=;
for (int i=;i<=len;i++)
x[sa[i]]=cmp(sa[i],sa[i-],k)?p-:p++;
if (p>len) break;
m1=p+;
}
for (int i=;i<=len;i++) rank[sa[i]]=i;
p=;
for (int i=;i<=len;i++)
{
if (rank[i]==) continue;
int j=sa[rank[i]-];
while (i+p<=len&&j+p<=len&&a[i+p]==a[j+p]) p++;
height[rank[i]]=p;
p=max(,p-);
}
}
int calc(int x,int y)
{
int k=L[y-x];
return max(st[k][x],st[k][y-(<<k)+]);
}
int divide(int l,int r)
{
int t=l,ans=r+;
while (l<=r)
{
int mid=(l+r)/;
if (calc(t,mid)) ans=min(ans,mid),r=mid-;
else l=mid+;
}
return ans;
}
int main()
{
scanf("%s",s1);
n=strlen(s1);
scanf("%s",s2);
m=strlen(s2);
scanf("%s",s3);
len1=strlen(s3);
get_fail();
kmp(s1,pd1,n);
kmp(s2,pd2,m);
for (int i=;i<=n;i++)a[i]=s1[i-]-'a'+,pd[i]=pd1[i-];
a[n+]=;len=n+;
for (int i=;i<=m;i++)a[++len]=s2[i-]-'a'+,pd[len]=pd2[i-];
get_sa();
for (int i=;i<=len;i++)st[][i]=pd[i];
for (int i=;i<=;i++)
for (int j=;j<=len;j++)
if (j+(<<i)-<=len)st[i][j]=max(st[i-][j],st[i-][j+(<<(i-))]);
int j=;
for (int i=;i<=len;i++)
{
if (<<(j+)<=i) j++;
L[i]=j;
}
int ans=;
for (int i=;i<=len;i++)
if (sa[i]<=n&&sa[i-]>n+||sa[i]>n+&&sa[i-]<=n)
{
int t=height[i];
int pos=divide(sa[i],sa[i]+height[i]-len1);
t=min(t,pos-sa[i]++len1-);
ans=max(ans,t);
}
printf("%d\n",ans);
}
bzoj3976的更多相关文章
随机推荐
- leecode第二十题(有效的括号)
class Solution { public: bool isValid(string s) { ,end=s.size()-; )//万万没想到,他把空字符串当成true了 return true ...
- 电脑用HDMI线分屏后,耳机或音箱没声音之完美解决!
现今,由于工作需要,很多人都偏爱给自己的电脑进行分屏,两个显示器同时连接在一台电脑上,并进行“扩展这些功能显示”,从而大大提高了工作积极性和工作效率.本人在进行分屏后遇到了耳机没有声音的问题,并进行了 ...
- pycharm设置连接github
pycharm与guthub连起来,推送代码会方便一些 教程很多,转发一个:https://www.cnblogs.com/feixuelove1009/p/5955332.html
- Top 命令解析
TOP是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中C ...
- The zero inflated negative binomial distribution
The zero-inflated negative binomial – Crack distribution: some properties and parameter estimation Z ...
- C#生成XSD规范
首先在开始菜单中找到:Visual Studio 2005 命令提示 大柏树按:VS2010在:开始—> Microsoft Visual Studio 2010 —> Visual St ...
- 2.2 调试 HelloWorld.exe 程序
- python3-知识扩展扫盲易忘-generator的用法
前部分转自: https://www.cnblogs.com/Tsukasa/p/6613934.html 通过列表list生成器,我们可以直接创建一个列表 ? 1 2 3 >>> ...
- php字段转义
addslashes() 函数返回在预定义的字符前添加反斜杠的字符串. 预定义字符是:在以下符号前加/ 单引号(') 双引号(") 反斜杠(\) NULL parse_str($str,$a ...
- MySQL使用的常见问题
(一)是否启动了服务器 如果没有启动报错:ERROR 2003 (HY000): Can't connect to MySQL server on ‘localhost' (10061) 解决方法:启 ...