博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 2946 SA/SAM
阅读量:6794 次
发布时间:2019-06-26

本文共 2738 字,大约阅读时间需要 9 分钟。

思路:

1. 二分+后缀数组

2.SAM

//By SiriusRen#include 
#include
#include
using namespace std;const int N=22222;int n,num,cntA[N],cntB[N],A[N],B[N],sa[N],rk[N],tsa[N],ht[N],rec[N],vis[10];char ch[5555],s[N];void SA(){ for(int i=1;i<=n;i++)cntA[s[i]]++; for(int i=1;i<=256;i++)cntA[i]+=cntA[i-1]; for(int i=n;i;i--)sa[cntA[s[i]]--]=i; rk[sa[1]]=1; for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(s[sa[i]]!=s[sa[i-1]]); for(int l=1;rk[sa[n]]
<<=1){ memset(cntA,0,sizeof(cntA)); memset(cntB,0,sizeof(cntB)); for(int i=1;i<=n;i++) cntA[A[i]=rk[i]]++, cntB[B[i]=i+l<=n?rk[i+l]:0]++; for(int i=1;i<=n;i++)cntA[i]+=cntA[i-1],cntB[i]+=cntB[i-1]; for(int i=n;i;i--)tsa[cntB[B[i]]--]=i; for(int i=n;i;i--)sa[cntA[A[tsa[i]]]--]=tsa[i]; rk[sa[1]]=1; for(int i=2;i<=n;i++) rk[sa[i]]=rk[sa[i-1]]+(A[sa[i]]!=A[sa[i-1]]||B[sa[i]]!=B[sa[i-1]]); } for(int i=1,j=0;i<=n;i++){ j=j?j-1:0; while(s[i+j]==s[sa[rk[i]-1]+j])j++; ht[rk[i]]=j; }}bool check(int mid){ int cnt=0; for(int i=1;i<=n;i++){ if(ht[i]
=num)return 1; }return 0;}int main(){ scanf("%d",&num); for(int i=1;i<=num;i++){ scanf("%s",ch+1); int templen=strlen(ch+1); for(int j=1;j<=templen;j++)s[++n]=ch[j],rec[n]=i; s[++n]=i; }SA(); int l=0,r=n,ans=0; while(l<=r){ int mid=(l+r)>>1; if(check(mid))ans=mid,l=mid+1; else r=mid-1; }printf("%d\n",ans);}

 

//By SiriusRen#include 
#include
#include
using namespace std;const int N=4050;int n,m;char s[N];struct SAM{ int ch[N][26],fa[N],dis[N],root,last,tot,ans[N],v[N],q[N],maxx[N]; void init(){root=last=tot=1;} int newnode(int v){
return dis[++tot]=v,tot;} void add(int x){ int p=last,np=newnode(dis[p]+1);last=np; for(;p&&!ch[p][x];p=fa[p])ch[p][x]=np; if(!p)fa[np]=root; else{ int q=ch[p][x]; if(dis[q]==dis[p]+1)fa[np]=q; else{ int nq=newnode(dis[p]+1); memcpy(ch[nq],ch[q],sizeof(ch[q])); fa[nq]=fa[q],fa[np]=fa[q]=nq; for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq; } } } void topsort(){ for(int i=1;i<=tot;i++)ans[i]=dis[i],v[dis[i]]++; for(int i=1;i<=tot;i++)v[i]+=v[i-1]; for(int i=tot;i;i--)q[v[dis[i]]--]=i; } void solve(){ memset(maxx,0,sizeof(maxx)); scanf("%s",s),n=strlen(s); int p=root,len=0; for(int i=0;i

 

转载于:https://www.cnblogs.com/SiriusRen/p/6771004.html

你可能感兴趣的文章
Android Studio 导入 AOSP 源码
查看>>
git status将文件状态标为renamed问题探究
查看>>
计算机开放电子书归档 2018
查看>>
跨域解决方案之nginx
查看>>
hibernate使用DetachedCriteria案例
查看>>
【Arduino基础教程】Moisture Sensor土壤湿度传感器
查看>>
tablesorter 使用
查看>>
一种用手机号码定位机主的理论方法
查看>>
underscore源码解析1
查看>>
html5从0到1-html5的简易数据库开发(18)
查看>>
spring cloud gateway 全局过滤器
查看>>
RAP Mock 工具模拟数据
查看>>
Confluence 6 确定一个生产系统备份方案
查看>>
在Chrome浏览器中保存的密码有多安全?
查看>>
撩人情话(三)
查看>>
JetBrains Product Pack for Students
查看>>
内存顺序(Memory Order)
查看>>
shiro实战系列(一)之入门实战
查看>>
BGP-RR 路由反射器工作原理
查看>>
算法作业:求一个集合中所有子集元素之和
查看>>