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的更多相关文章
随机推荐
- JS client(X,Y)、screen(X,Y)、page(X,Y)的区别
clientX:光标相对于当前窗口的水平位置: clientY :光标相对于当前窗口的垂直位置: screenX :光标相对于该屏幕的水平位置: screenY:光标相对于该屏幕的垂直位置: page ...
- Linux 端口信息查看
//查看方法①lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000 lsof -i 用以显示符合条件的进程情况,lsof(list open fi ...
- Codeforces 1053 C - Putting Boxes Together
C - Putting Boxes Together 思路: 求带权中位数 用树状数组维护修改 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) ...
- slf4j/logback: logging日志的配置
slf4j/logback: logging日志的配置 import依赖: import org.slf4j.Logger;import org.slf4j.LoggerFactory;private ...
- caffe---mnist数据集训练与测试
1.数据.mnist_test_lmdb和mnist_train_lmdb数据 2.路径. (1)修改lenet_train_test.prototxt文件,训练和测试两处 source: " ...
- Windows 上安装 Scala
在安装 Scala 之前需要先安装 Java 环境,具体安装的详细方法就不在这里描述了. 您可以自行搜索我们网站中的内容获得其他网站的帮助来获得如何安装 Java 环境的方法. 接下来,我们可以从 S ...
- linux基础知识(1)
1.date man date :查看帮助 1. date [OPTION]... [+FORMAT]:显示时间 ,format表示格式符号 例如: date :Sun Dec 23 21:45:34 ...
- 1.2 面向对象 Object-oriented
前导课程 1.UML(统一建模语言) 2.OOAD Concept(Object-oriented Analysis and Design 概念) 3.Design Pattern(设计模式) 4.面 ...
- 非常可乐 HDU - 1495
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多.但see ...
- GIL锁,线程池
内容梗概: 1.线程队列 2.线程池 3.GIL锁 1.线程队列 1.1先进先出队列(FIFO)import queueq = queue.Queue(3)q.put(1)q.put(2)q.put( ...