字符串(后缀自动机):COGS 2399. 循环同构
2016-07-22 22:08
369 查看
这道题直接看代码吧。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int maxn=2000010; int fa[maxn],len[maxn],rit[maxn],w[maxn],sa[maxn]; int n,Q,cnt,lst,ch[maxn][26],vis[maxn]; char s[maxn]; struct SAM{ SAM(){ memset(fa,0,sizeof(fa)); memset(len,0,sizeof(len)); memset(rit,0,sizeof(rit)); cnt=lst=1; } void Insert(int c){ int p=lst,np=lst=++cnt;len[np]=len[p]+1; while(p&&!ch[p][c])ch[p][c]=np,p=fa[p]; if(!p)fa[np]=1; else{ int q=ch[p][c]; if(len[p]+1==len[q])fa[np]=q; else{ int nq=++cnt;len[nq]=len[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); fa[nq]=fa[q];fa[q]=fa[np]=nq; while(ch[p][c]==q)ch[p][c]=nq,p=fa[p]; } } } void Prepare(){ //rit[1]=1; for(int i=1,p=1;i<=n;i++) rit[p=ch[p][s[i]-'a']]+=1; for(int i=1;i<=cnt;i++)w[len[i]]+=1; for(int i=1;i<=cnt;i++)w[i]+=w[i-1]; for(int i=1;i<=cnt;i++)sa[--w[len[i]]]=i; for(int i=cnt;i;i--)rit[fa[sa[i]]]+=rit[sa[i]]; } void Solve(int tim){ scanf("%s",s+1);n=strlen(s+1); for(int i=1;i<=n;i++)s[n+i]=s[i]; int p=1,ans=0,l=0; for(int i=1,c;i<2*n;i++){ c=s[i]-'a'; while(p!=1&&!ch[p][c]) {p=fa[p];l=len[p];} if(!ch[p][c])l=0; else{p=ch[p][c];l+=1;} if(l>=n){ while(len[fa[p]]>=n)p=fa[p],l=len[p]; if(vis[p]!=tim)vis[p]=tim,ans+=rit[p]; } } printf("%d\n",ans); } }sam; int main(){ freopen("rotate.in","r",stdin); freopen("rotate.out","w",stdout); scanf("%s%d",s+1,&Q);n=strlen(s+1); for(int i=1;i<=n;i++)sam.Insert(s[i]-'a'); sam.Prepare();while(Q--)sam.Solve(Q+1); return 0; }
相关文章推荐
- 信使——图论算法
- 【转载】信号量
- java学习之路-基础语法-运算符
- Android混淆心得
- CentOS 上安装GCC GDB 和VIM 开发环境
- UVa 1625
- 关于Android Studio里的Gradle
- web前端css简单
- 4000 冷却算法综合排名改进模型-R实现代码
- Android之多线程生成GIF
- cocoapods插件不能使用的解决方法
- HDU 5620 KK's Steel (斐波那契序列)
- Android基础总结(4)——广播接收器
- TextView 设置行高并垂直居中
- 网上的写法都什么辣鸡bzoj4004
- IIS 7 网站权限问题
- iOS 应用程序开发官方中文手册
- 欢迎使用CSDN-markdown编辑器
- Service的理解和使用
- 数据结构-----------B树