字符串(后缀自动机):COGS 2399. 循环同构



这道题直接看代码吧。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
int fa[maxn],len[maxn],rit[maxn],w[maxn],sa[maxn];
int n,Q,cnt,lst,ch[maxn][],vis[maxn];
char s[maxn];
struct SAM{
SAM(){
memset(fa,,sizeof(fa));
memset(len,,sizeof(len));
memset(rit,,sizeof(rit));
cnt=lst=;
} void Insert(int c){
int p=lst,np=lst=++cnt;len[np]=len[p]+;
while(p&&!ch[p][c])ch[p][c]=np,p=fa[p];
if(!p)fa[np]=;
else{
int q=ch[p][c];
if(len[p]+==len[q])fa[np]=q;
else{
int nq=++cnt;len[nq]=len[p]+;
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=,p=;i<=n;i++)
rit[p=ch[p][s[i]-'a']]+=;
for(int i=;i<=cnt;i++)w[len[i]]+=;
for(int i=;i<=cnt;i++)w[i]+=w[i-];
for(int i=;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+);n=strlen(s+);
for(int i=;i<=n;i++)s[n+i]=s[i];
int p=,ans=,l=;
for(int i=,c;i<*n;i++){
c=s[i]-'a';
while(p!=&&!ch[p][c])
{p=fa[p];l=len[p];}
if(!ch[p][c])l=;
else{p=ch[p][c];l+=;} 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+,&Q);n=strlen(s+);
for(int i=;i<=n;i++)sam.Insert(s[i]-'a');
sam.Prepare();while(Q--)sam.Solve(Q+);
return ;
}
字符串(后缀自动机):COGS 2399. 循环同构的更多相关文章
- 模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合)
模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合) Code: #include <bits/stdc++.h> using namespace std; #define ...
- [TJOI2019]甲苯先生和大中锋的字符串——后缀自动机+差分
题目链接: [TJOI2019]甲苯先生和大中锋的字符串 对原串建后缀自动机并维护$parent$树上每个点的子树大小,显然子树大小为$k$的节点所代表的子串出现过$k$次,那么我们需要将$[len[ ...
- Wannafly Camp 2020 Day 2D 卡拉巴什的字符串 - 后缀自动机
动态维护任意两个后缀的lcp集合的mex,支持在串末尾追加字符. Solution 考虑在 SAM 上求两个后缀的 LCP 的过程,无非就是找它们在 fail 树上的 LCA,那么 LCP 长度就是这 ...
- bzoj3756pty的字符串(后缀自动机+计数)
题目描述 题解 我们可以先对trie树建出广义SAM,然后维护一下right集合大小(注意right集合在广义SAM上的维护方式). 然后把匹配穿往广义SAM上匹配,假设现在匹配到了x节点,那么x的所 ...
- Tjoi2019 甲苯先生和大中锋的字符串 后缀自动机_差分
tjoi胆子好大,直接出了两道送分题...... 都 9102 年了,还有省选出模板题QAQ...... Code: #include <bits/stdc++.h> #define se ...
- POJ 1509 循环同构的最小表示法
题目大意: 给定一个字符串,可以把一段尾部接到头部,这样找到一个最小的字符串 方案一: 利用循环同构中找最小表示的方法来解决 论文参考http://wenku.baidu.com/view/438ca ...
- uva 719 Glass Beads(后缀自动机)
[题目链接] https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=524&am ...
- hihocoder 后缀自动机五·重复旋律8 求循环同构串出现的次数
描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 小Hi发现旋律可以循环,每次把一段旋律里面最前面一个音换到最后面就成为了原旋律的“循环相似旋律”,还可以 ...
- 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)
模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...
随机推荐
- UICollectionView reloadData后cell被隐藏
在使用UICollectionView的页面执行: [self.collectionView reloadData]; 执行后,页面变为空白页,调试发现,执行reloadData 后UICollect ...
- 第七章----pwm蜂鸣器
Linux代码的重用: 在头文件中加载即可使用到原来所有的功能,还有动态方式就是一个驱动使用另一个驱动的资源. 对于像蜂鸣器这样的实验,它的内部文件有很多,所有要有很多的源代码以用于妥善管理. 有多个 ...
- ZOJ 3905 Cake(贪心+dp)
动态规划题:dp[i][j]表示有i个Cake,给了Alice j个,先按照b排序,这样的话,能保证每次都能成功给Alice Cake,因为b从大到小排序,所以Alice选了j个之后,Bob最少选了j ...
- Css实现透明效果,兼容IE8
Css实现透明效果,兼容IE8 >>>>>>>>>>>>>>>>>>>>> ...
- 什么是php命名空间
php命名空间是在5.3版本后加入的,命名空间反过来就是空间命名,在这里的空间命名就像window下的文件夹命名,命名空间用关键字namespace来定义.在这里用文件夹举三个例子,比如相对于test ...
- Oracle分区表学习
(1) 表空间及分区表的概念表空间: 是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表, 所以称作表空间.分区表: 当表中的数据量不断增大,查询数据的速度就会变慢,应 ...
- C# 多线程、结构体
struct IpAndPort { public string Ip; public int Port; } private void Form1_Load(object sender, Event ...
- Linux数据写操作改进
Linux的IO操作中数据的写函数int nwrite = write(int fd,void* buf ,int len)表示向fd文件描述符写入len个字节长度的数据报文,但是这并不能保证真正向内 ...
- Codeforces 527E Data Center Drama(欧拉回路)
题意: 给定一个无向图连通图,把这个的无向边变成有向边,并添加最少的有向边使这个图每个结点的出度为偶数. Solution: 题目很长,并且很多条件说的不太直接,确实不太好懂. 首先先看得到的无向图, ...
- 【BZOJ2809】【splay启发式合并】dispatching
Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级. ...