这里给出来一个后缀自动机的题解.

考虑对 $s$ 的正串和反串分别建后缀自动机.

对于正串的每个节点维护 $endpos$ 的最小值.

对于反串的每个节点维护 $endpos$ 的最大值.

这两个东西通过一个简单的基数排序就可以实现.

将 $p$ 的正串在正串的 SAM 上去匹配,一直
匹配到匹配不了为止,并记录 $p[i]$ 在正串中自动机节点上 $endpos$ 的最小值 $a[i]$.

对 $p$ 的反串也进行相同的处理,记录 $endpos$ 的最大值 $b[i]$.

正串中的 $endpos$ 就是 $p[1...i]$ 中 $i$ 的最小结束位置,那么反串中的 $endpos$ 就是 $p[i...length(p)]$ 中 $i$ 的最大开始位置.

所以,我们只需枚举 $1$~length(p) 并判断 $a[i]&&b[i]&&a[i]<b[i+1]$ 即可.

如果满足这个条件,就说明这个询问是有解的.

当然,要注意判断一下长度为 $1$ 的情况,这显然是无解的.

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 200004
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
inline void getmin(int &a,int b) { if(b<a)a=b; }
inline void getmax(int &a,int b) { if(b>a)a=b; }
int a[1002],b[1002],n;
char str[N],P[N];
struct SAM
{
int c[N],rk[N],tot,last;
struct Node { int len,ch[27],f,minv,maxv; }t[N];
void init() { last=tot=1; }
inline void extend(int c,int lst)
{
int np=++tot,p=last;
last=np, t[np].len=t[p].len+1;
while(p&&!t[p].ch[c]) t[p].ch[c]=np,p=t[p].f;
if(!p) t[np].f=1;
else
{
int q=t[p].ch[c];
if(t[q].len==t[p].len+1) t[np].f=q;
else
{
int nq=++tot;
t[nq].len=t[p].len+1,t[nq].minv=t[nq].maxv=t[q].maxv;
memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch));
t[nq].f=t[q].f,t[q].f=t[np].f=nq;
while(p&&t[p].ch[c]==q) t[p].ch[c]=nq,p=t[p].f;
}
}
t[np].minv=t[np].maxv=lst;
}
inline void prepare()
{
int i,u;
for(i=1;i<=tot;++i) c[i]=0;
for(i=1;i<=tot;++i) ++c[t[i].len];
for(i=1;i<=tot;++i) rk[c[t[i].len]--]=i;
for(i=tot;i>=1;--i)
u=rk[i],getmin(t[t[u].f].minv,t[u].minv),getmax(t[t[u].f].maxv,t[u].maxv);
}
}t1,t2;
int main()
{
int i,j,m,re=0,ans=0;
// setIO("input");
t1.init(),t2.init();
scanf("%s",str+1),n=strlen(str+1);
for(i=1;i<=n;++i) t1.extend(str[i]-'A',i);
for(i=n;i>=1;--i) t2.extend(str[i]-'A',i);
t1.prepare(),t2.prepare(),scanf("%d",&m);
for(i=1;i<=m;++i)
{
int len,p;
scanf("%s",P+1),len=strlen(P+1),memset(a,0,sizeof(a)),memset(b,0,sizeof(b));
for(p=j=1;j<=len;++j)
{
int c=P[j]-'A';
if(t1.t[p].ch[c]) a[j]=t1.t[t1.t[p].ch[c]].minv,p=t1.t[p].ch[c]; else break;
}
for(p=1,j=len;j>=1;--j)
{
int c=P[j]-'A';
if(t2.t[p].ch[c]) b[j]=t2.t[t2.t[p].ch[c]].maxv,p=t2.t[p].ch[c]; else break;
}
re=0;
for(j=1;j<len;++j) {
if(a[j]&&b[j+1]&&a[j]<b[j+1]) re=1;
}
if(a[len]) re=1;
if(len==1) re=0;
ans+=re;
}
printf("%d\n",ans);
return 0;
}

  

CF 149E Martian Strings 后缀自动机的更多相关文章

  1. HDU 6208 The Dominator of Strings 后缀自动机

    The Dominator of Strings Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java ...

  2. Codechef2015 May - Chef and Strings (后缀自动机)

    用后缀自动机统计出出现1~n次的串的数量f[i] 对于ans[k]=sigma(f[i]*C(i,k)) i>=k ; mo=; ..maxn] of dword; nt:..maxn,'a'. ...

  3. Codeforces 452E Three Strings(后缀自动机)

    上学期很认真地学了一些字符串的常用工具,各种 suffix structre,但是其实对后缀自动机这个部分是理解地不太透彻的,以致于看了师兄A这题的代码后,我完全看不懂,于是乎重新看回一些学习后缀自动 ...

  4. CodeForces 149E Martian Strings exkmp

    Martian Strings 题解: 对于询问串, 我们可以从前往后先跑一遍exkmp. 然后在倒过来,从后往前跑一遍exkmp. 我们就可以记录下 对于每个正向匹配来说,最左边的点在哪里. 对于每 ...

  5. CF 235C. Cyclical Quest [后缀自动机]

    题意:给一个主串和多个询问串,求询问串的所有样子不同的周期同构出现次数和 没有周期同构很简单就是询问串出现次数,|Right| 有了周期同构,就是所有循环,把询问串复制一遍贴到后面啊!思想和POJ15 ...

  6. CF 452E. Three strings(后缀数组+并查集)

    传送门 解题思路 感觉这种题都是套路之类的??首先把三个串并成一个,中间插入一些奇怪的字符,然后跑遍\(SA\).考虑按照\(height\)分组计算,就是每个\(height\)只在最高位计算一次, ...

  7. codeforces 149E . Martian Strings kmp

    题目链接 给一个字符串s, n个字符串str. 令tmp为s中不重叠的两个连续子串合起来的结果, 顺序不能改变.问tmp能形成n个字符串中的几个. 初始将一个数组dp赋值为-1. 对str做kmp, ...

  8. 字符串(后缀自动机):Codeforces Round #129 (Div. 1) E.Little Elephant and Strings

    E. Little Elephant and Strings time limit per test 3 seconds memory limit per test 256 megabytes inp ...

  9. CodeForces - 616F:Expensive Strings (后缀自动机)

    You are given n strings ti. Each string has cost ci. Let's define the function of string , where ps, ...

随机推荐

  1. Oozie 3.3.1安装

    软件安装路径 软件名称 版本 安装路径 jdk 1.6.0_12 /usr/java/jdk1.6.0_12 maven 3.1.0 /usr/local//apache-maven-3.1.0 Oo ...

  2. [官网]关于EPEL

    EPEL/zh-cn https://fedoraproject.org/wiki/EPEL/zh-cn Contents [hide]  1企业版 Linux 附加软件包(EPEL) 1.1什么是企 ...

  3. mysql分表规则(转)

    author:skatetime:2013/05/14 Mysql分表准则 在大量使用mysql时,数据量大.高访问时,为了提高性能需要分表处理,简介下mysql分表的标准,后续会继续补充 环境:业务 ...

  4. Java第四周总结报告

    本周做了什么? 学习了Java的面向对象知识,包括对类,对象,抽象的理解 下周准备做什么? 学习Java面向对象的有关知识,包括对象与类,继承关系等内容 代码联系时间五个小时,看书四个小时. 本周遇到 ...

  5. 【6.18校内test】T2分数线划定

    分数线划定[题目链接] 这道题也不是什么难题,思路一带而过吧: SOLUTION: First.输入n,m,计算m*1.5的值,接着输入编号和成绩,然后我的做法是在输入编号成绩之后,开一个101大小的 ...

  6. phpstorm配置phpunit进行单元测试

    1.配置单元测试目录: (1)autoload.php <?php function autoloader($dir){ spl_autoload_register(function($name ...

  7. Java Web开发技术教程入门-静态网页技术

        昨天了解了构建动态网站的几种技术:Servlet技术.JSP技术,ASP技术和ASP.NET技术以及PHP技术.昨天的精髓在于JSP技术的运行原理:通过用户请求JSP文件,首先检查JSP文件的 ...

  8. POJ 3249 Test for Job (拓扑排序+DP)

    POJ 3249 Test for Job (拓扑排序+DP) <题目链接> 题目大意: 给定一个有向图(图不一定连通),每个点都有点权(可能为负),让你求出从源点走向汇点的路径上的最大点 ...

  9. 08、beta-actin和GAPDH的3'/5'比值

    一.大部分的基因都有beta-action基因和GAPDH基因,很多Affymetrix芯片都将它们设为一组观察RNA降解程度的内参基因.mRNA是按照5’至3’的顺序来降解的,通过比较它们3’相对于 ...

  10. 解决iframe缓存机制导致页面不清除缓存不刷新页面的bug

    在使用iframe时,已有页面嵌套了一个iframe页面,当这个页面提交后再次跳转到本页面时,原本iframe内的页面应该刷新数据的,结果未刷新,需要清除缓存后才刷新. 解决方案: var fresh ...