CF 149E Martian Strings 后缀自动机
这里给出来一个后缀自动机的题解.
考虑对 $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 后缀自动机的更多相关文章
- HDU 6208 The Dominator of Strings 后缀自动机
The Dominator of Strings Time Limit: 3000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java ...
- 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'. ...
- Codeforces 452E Three Strings(后缀自动机)
上学期很认真地学了一些字符串的常用工具,各种 suffix structre,但是其实对后缀自动机这个部分是理解地不太透彻的,以致于看了师兄A这题的代码后,我完全看不懂,于是乎重新看回一些学习后缀自动 ...
- CodeForces 149E Martian Strings exkmp
Martian Strings 题解: 对于询问串, 我们可以从前往后先跑一遍exkmp. 然后在倒过来,从后往前跑一遍exkmp. 我们就可以记录下 对于每个正向匹配来说,最左边的点在哪里. 对于每 ...
- CF 235C. Cyclical Quest [后缀自动机]
题意:给一个主串和多个询问串,求询问串的所有样子不同的周期同构出现次数和 没有周期同构很简单就是询问串出现次数,|Right| 有了周期同构,就是所有循环,把询问串复制一遍贴到后面啊!思想和POJ15 ...
- CF 452E. Three strings(后缀数组+并查集)
传送门 解题思路 感觉这种题都是套路之类的??首先把三个串并成一个,中间插入一些奇怪的字符,然后跑遍\(SA\).考虑按照\(height\)分组计算,就是每个\(height\)只在最高位计算一次, ...
- codeforces 149E . Martian Strings kmp
题目链接 给一个字符串s, n个字符串str. 令tmp为s中不重叠的两个连续子串合起来的结果, 顺序不能改变.问tmp能形成n个字符串中的几个. 初始将一个数组dp赋值为-1. 对str做kmp, ...
- 字符串(后缀自动机):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 ...
- CodeForces - 616F:Expensive Strings (后缀自动机)
You are given n strings ti. Each string has cost ci. Let's define the function of string , where ps, ...
随机推荐
- Angular5 *ngIf 和 hidden 的区别
问题 项目中遇到一个问题,有一个过滤查询的面板,需要通过一个展开折叠的button,来控制它的show 和 hide.这个面板中,有一个Select 组件,一个 input 查询输入框. 原来代码是: ...
- jmeter对websocket进行压测
参考文档:https://blog.csdn.net/weixin_39430584/article/details/81508451 ①脚本调通 ②添加并发量和持续时间 ③看服务器指标
- HTML标签-->段落,格式,文本
只有努力奔跑,才能一直停留在原地. <!--段落标签--> <h1>默认向左</h1> <h1 align="right">向右对齐 ...
- CDH开启ldap
参考: 官网ldap: https://www.cloudera.com/documentation/enterprise/6/6.2/topics/cm_sg_ldap_grp_mappings.h ...
- sqlserver with(nolock)而mysql 不需nolock
nolock 是 SQL Server 特有的功能. 例如:对于一个表 A,更新了一行,还没有commit,这时再select * from A 就会死锁.用select * from A(noloc ...
- gcc数据结构对齐之:why.
gcc 支持 aligned 和 packed 属性指定数据对齐,那么在了解对齐规则之前,需要解决第一个以为,我们为什么需要数据对齐?请看下图: 相信学过汇编的朋友都很熟悉这张图,这张图就是CPU与内 ...
- 优化 Karatsuba 乘法(老物)
虽然写好了我自己用的a*启发函数但还是有些不尽人意,如果通过数学分析确定不出问题可以工作了的话应该就会发出来了 // Karatsuba 递归式距离推导 // h(x) = f(x) * g(x):/ ...
- Linux设置远程免密登录
1.生成公钥 / 私钥对 [root@localhost ~]# ssh-keygen -t rsa -P '' -P表示密码,-P '' 就表示空密码,也可以不用-P参数,这样就要三车回车,用-P就 ...
- React Native 底部导航栏
首先安装:npm install react-native-tab-navigator 然后再引入文件中 import TabNavigator from 'react-native-tab ...
- Ant 学习
到了新公司,发现公司使用ant 来代码生成.本来学习后写下来.在网上找到一篇教程,实在是非常给力... 就把连接记下来吧:http://www.blogjava.net/amigoxie/archiv ...