CF235C
来源:互联网 发布:mac系统备忘录怎么复原 编辑:程序博客网 时间:2024/06/05 11:15
传送门
题意就是你有一个母串,每次查询给出一个串,问母串有多少个子串和查询串循环同构。
首先建出母串的SAM。
再将询问串复制一遍,在母串上跑就行了。
但直接这样是有问题的,比方说有一个串”abc”,复制一遍后就是”abcabc”,匹配到第二个a的时候,发现母串没有”abca”这个子串,但却有”bca”这个子串,怎么办?
其实只要加一句话for(;step[pre[u]]+1>=l;z=step[u=pre[u]]);
就行了。
为什么这样就行了?
如果step[pre[u]]+1>=l
,那么已经匹配的长度必定也大于等于询问传参。
因为对于一个字符串,如果在SAM上走到了一个节点,那么该字符串一定还存在一个后缀,能在SAM上走到此节点的pre节点
然后我们可以发现这相当于通过pre边来删除首部已匹配的字符。
这道题其实了我们,不要只想着复制主串,有时想想复制询问串也是可行的。
下面就是蒟蒻的代码,一开始桶排数组开小,WA了一发
#include<cstdio>#include<cstring>const int N=2000005;int ch[N][26],xb,step[N],p,np,q,nq,lst,n,i,x,u,l,a[N],b[N],s[N],z,ans,vi[N],pre[N];int cnt[26];char c[N];int main(){ scanf("%s",c+1);lst=xb=1; for(i=1;c[i];++i){ step[np=++xb]=step[p=lst]+1;++cnt[x=c[i]-'a']; for(;!ch[p][x];p=pre[p])ch[p][x]=np; if(p){ q=ch[p][x]; if(step[p]+1!=step[q]){ step[nq=++xb]=step[p]+1; memcpy(ch[nq],ch[q],104); pre[nq]=pre[q]; pre[q]=pre[np]=nq; for(;ch[p][x]==q;p=pre[p])ch[p][x]=nq; }else pre[np]=q; }else pre[np]=1; s[lst=np]=1; } for(i=1;i<=xb;++i)++b[step[i]]; for(i=1;b[i];++i)b[i]+=b[i-1]; for(i=1;i<=xb;++i)a[b[step[i]]--]=i; for(i=xb;i;--i)s[pre[a[i]]]+=s[a[i]]; scanf("%d",&n); while(n){ scanf("%s",c+1);l=strlen(c+1); if(l==1){printf("%d\n",cnt[c[1]-'a']);--n;continue;} memcpy(c+l+1,c+1,l-1); u=1;z=ans=0; for(i=1;i<l<<1;++i){ x=c[i]-'a'; if(!ch[u][x]){ for(;u && !ch[u][x];u=pre[u]); if(ch[u][x])z=step[u]+1,u=ch[u][x]; else z=0,u=1; }else u=ch[u][x],++z; if(z>=l && vi[u]!=n)vi[u]=n,ans+=s[u]; for(;step[pre[u]]+1>=l;z=step[u=pre[u]]); } printf("%d\n",ans);--n; } return 0;}
阅读全文
0 0
- cf235c
- CF235C
- Cyclical Quest CF235C
- CF235C Cyclical Quest
- [CF235C] Cyclical Quest
- 字符串练习题:【CF235C】 Cyclical Quest(SAM )
- 单片机显示方案-OLED
- 对前端获取的文件流进行加密和解密处理
- Linux上vi(vim)编辑器使用教程
- POI技术处理Excel表 .xls ..xlsx两种格式的导入操作
- 机器学习之线性回归 Linear Regression(三)scikit-learn算法库
- CF235C
- AES,SHA,SHA1,MD5加密及解密技术
- JavaScript中ajax的使用
- liunx docker 安装 zookeeper
- [BZOJ2742]-[HEOI2012]Akai的数学作业-画柿子
- 设计模式---代理模式
- 位置型PID算法
- selector+shape使用工具类
- clear、clc、close的区别