差分后即求多串LCS。先考虑两个串怎么做。对第一个串建SAM,第二个串在上面跑即可,任意时刻走到的节点表示的都是第二个串的当前前缀在第一个串中出现的最长的后缀,具体计算长度时每走一个字符长度+1,跳fail时将长度重设为当前节点maxlen即可。

  扩展到多串,同样对第一个串建SAM,后面每个串在上面跑一遍,每走到一个节点就记录当前匹配长度,每个节点对所有串取min,再在所有节点中找max即可。注意每个串跑完时都要按parent树更新一遍节点的记录值,因为能在某点匹配就一定可以在它的所有父亲处以最长长度匹配。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
#define ll long long
#define N 2010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,a[N][N],cnt=1,last=1,len[N],fail[N],u[N],v[N],id[N];
map<int,int> son[N];
void ins(int c,int n)
{
int x=++cnt,p=last;last=x;len[x]=len[p]+1;
while (!son[p][c]) son[p][c]=x,p=fail[p];
if (!p) fail[x]=1;
else
{
int q=son[p][c];
if (len[q]==len[p]+1) fail[x]=q;
else
{
int y=++cnt;
len[y]=len[p]+1;
son[y]=son[q];
fail[y]=fail[q],fail[x]=fail[q]=y;
while (son[p][c]==q) son[p][c]=y,p=fail[p];
}
}
}
void run(int n,int *a)
{
memset(v,0,sizeof(v));
int k=1,l=0;
for (int i=1;i<=n;i++)
{
while (!son[k][a[i]]&&k) k=fail[k],l=len[k];
if (!k) k=1,l=0;
else l++,k=son[k][a[i]],v[k]=max(v[k],l);
}
for (int i=1;i<=cnt;i++) if (v[id[i]]) v[fail[id[i]]]=len[fail[id[i]]];
for (int i=1;i<=cnt;i++) u[i]=min(u[i],v[i]);
}
bool cmp(const int&a,const int&b)
{
return len[a]>len[b];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4698.in","r",stdin);
freopen("bzoj4698.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=1;i<=n;i++)
{
a[i][0]=read();
for (int j=1;j<=a[i][0];j++) a[i][j]=read();
for (int j=a[i][0];j>=1;j--) a[i][j]-=a[i][j-1];
for (int j=1;j<a[i][0];j++) a[i][j]=a[i][j+1];
a[i][0]--;
}
for (int i=1;i<=a[1][0];i++) ins(a[1][i],i);
memset(u,42,sizeof(u));
for (int i=1;i<=cnt;i++) id[i]=i;
sort(id+1,id+cnt+1,cmp);
for (int i=2;i<=n;i++) run(a[i][0],a[i]);
int ans=0;
for (int i=1;i<=cnt;i++) ans=max(ans,min(len[i],u[i]));
cout<<ans+1;
return 0;
}

  

BZOJ4698 SDOI2008Sandy的卡片(后缀自动机)的更多相关文章

  1. [BZOJ4698][SDOI2008]Sandy的卡片(后缀自动机)

    差分之后就是求多串LCS. 对其中一个串建SAM,然后把其它串放在上面跑. 对SAM上的每个状态都用f[x]记录这个状态与当前串的最长匹配长度,res[x]是对每次的f[x]取最小值.答案就是res[ ...

  2. BZOJ 4698: Sdoi2008 Sandy的卡片 [后缀自动机]

    4698: Sdoi2008 Sandy的卡片 题意:差分后就是多个串LCS SAM+map大法好 模板打错 智力-2 #include <iostream> #include <c ...

  3. BZOJ 后缀自动机四·重复旋律7

    后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的 ...

  4. 【Codeforces235C】Cyclical Quest 后缀自动机

    C. Cyclical Quest time limit per test:3 seconds memory limit per test:512 megabytes input:standard i ...

  5. 【hihocoder#1413】Rikka with String 后缀自动机 + 差分

    搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...

  6. 【BZOJ-3998】弦论 后缀自动机

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2018  Solved: 662[Submit][Status] ...

  7. HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  8. hihoCoder 后缀自动机三·重复旋律6

    后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi ...

  9. hihoCoder #1445 : 后缀自动机二·重复旋律5

    #1445 : 后缀自动机二·重复旋律5 时间限制:10000ms 单点时限:2000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...

随机推荐

  1. Java核心复习——J.U.C LinkedBlockingQueue源码分析

    参考文档 LinkedBlockingQueue和ArrayBlockingQueue的异同

  2. 咏南中间件和开发框架全面支持DELPHI10.3.2

    咏南中间件和开发框架全面支持DELPHI10.3.2 易博龙公司2019年7月12日发布了RAD STUDIO10.3.2正式版本. 咏南中间件自2019年7月14日始,中间件.CS框架.WEB框架. ...

  3. HBase-概述

    一种分布式.可扩展.支持海量数据存储的 NoSQL 数据库. 逻辑上,HBase 的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列.但从 HBase 的底层物理存储结构(K-V)来看,HB ...

  4. 【Canvas】勾画调和级数Harmonic series 曲线 y=1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+....

    相关资料:https://baike.baidu.com/item/%E8%B0%83%E5%92%8C%E7%BA%A7%E6%95%B0/8019971?fr=aladdin 调和级数(英语:Ha ...

  5. OpenJudge计算概论-数字求和

    /*========================================================= 数字求和 总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个 ...

  6. body-parser 解析post数据

    安装 $ npm install body-parser API var bodyPaeser =require('body-parser') bodyParse.raw(option) 将请求体内容 ...

  7. 012-多线程-JUC集合-Queue-SynchronousQueue和LinkedTransferQueue

    一.SynchronousQueue概述 SynchronousQueue是一个不存储元素的队列.每一个put操作必须等待一个take操作,否则不能继续添加元素. 它支持公平访问队列.默认情况下线程采 ...

  8. 深入理解Java虚拟机 - 书评

    谈起<深入理解java虚拟机>这本书,让我印象深刻的就是换工作跳槽面试的时候,当时刚进入java开发这个行业的时候,平时只是做一些对数据库的增删改查等功能,当自己技术增长一些的时候,就开始 ...

  9. 查看php 某个服务的进程数

    查看进程就是使用ps命令而已,只不顾ps的参数太多了. 使用php查询的话,必须要开启几个函数(可以执行外部程序的函数),参考官网:http://php.net/manual/zh/book.exec ...

  10. Mac下载工具软件提示损坏

    今天装Navicat的时候一直报错文件损坏,最后请教别人才知道,这里记录下: 原因: Mac默认不允许任何来源的软件安装,安全问题,需要我们设置下即可: 解决方法: 方法一: 方法二: 终端输入命令: ...