正题

题目链接:https://www.luogu.com.cn/problem/CF235C


题目大意

一个文本串sss。询问nnn个匹配的本质不同的循环同构在文本串中出现了几次。


解题思路

我们匹配完原串之后,相当与每次在头部删去一个字符然后又在末尾加上一个字符。使用SAMSAMSAM匹配的话,发现每次在parentsparentsparents树上条就相当于删去头部的字符,因为parentsparentsparents树上的祖先是属于同一个endposendposendpos类的,所以后面的字符不会改变,我们一直跳到满足L∈[minlenx,maxlenx]L\in [minlen_x,maxlen_x]L∈[minlenx​,maxlenx​]的节点即可。

要求本质不同的话,就直接在统计过答案的点打上标记,后面不统计即可。

时间复杂度O(∣s∣+∑i=1n∣t∣)O(|s|+\sum_{i=1}^n|t|)O(∣s∣+∑i=1n​∣t∣)


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e6+10;
int n,cnt,len[N],fa[N],siz[N],ch[N][26];
int last,ans,mark[N],c[N],p[N];
char s[N];
void Insert(int c){int p=last,np=last=++cnt;len[np]=len[p]+1;siz[np]++;for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;if(!p)fa[np]=1;else{int q=ch[p][c];if(len[q]==len[p]+1)fa[np]=q;else{int nq=++cnt;len[nq]=len[p]+1;memcpy(ch[nq],ch[q],sizeof(ch[nq]));fa[nq]=fa[q];fa[np]=fa[q]=nq;for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq;}}return;
}
void solve(int p){int l=strlen(s),L=0;int x=1;for(int i=0;i<l;i++){int c=s[i]-'a';while(x!=1&&!ch[x][c])x=fa[x],L=len[x];if(ch[x][c])x=ch[x][c],L++;}if(L==l&&mark[x]!=p)mark[x]=p,ans+=siz[x];for(int i=0;i<l-1;i++){int c=s[i]-'a';while(x!=1&&!ch[x][c])x=fa[x],L=len[x];if(ch[x][c])x=ch[x][c],L++;if(L>l&&--L==len[fa[x]])x=fa[x];if(L==l&&mark[x]!=p)mark[x]=p,ans+=siz[x];}return;
}
int main()
{scanf("%s",s);int l=strlen(s);cnt=last=1;for(int i=0;i<l;i++)Insert(s[i]-'a');for(int i=1;i<=cnt;i++) c[len[i]]++;for(int i=1;i<=l;i++)   c[i]+=c[i-1];for(int i=1;i<=cnt;i++) p[c[len[i]]--]=i;for(int i=cnt;i>=1;i--) siz[fa[p[i]]]+=siz[p[i]];scanf("%d",&n);for(int i=1;i<=n;i++){ans=0;scanf("%s",s),solve(i);printf("%d\n",ans);}return 0;
}

CF235C-Cyclical Quest【SAM】相关推荐

  1. 【SAM】51Nod1647 小Z的Trie

    [前言] 本来是用来愉悦身心的题目,结果因为自己一些zz错误弄得很不愉悦. [题目] 51Nod 给定一棵Trie\text{Trie}Trie(实际上是给出字符串自己建),QQQ次询问Trie\te ...

  2. 【SAM】BZOJ5137 [Usaco2017 Dec] Standing Out from the Herd

    [题目] lydsy 给定 n n n个字符串,对于每个字符串,问只在这个字符串中出现的子串有多少个. n , ∑ ∣ S ∣ ≤ 1 0 5 n,\sum|S|\leq 10^5 n,∑∣S∣≤10 ...

  3. 【SAM】差异(P4248)

    正题 P4248 题目大意 设TiT_iTi​为第i个字符开始的后缀,求: ∑i=1n∑j=i+1nlen(Ti)+len(Tj)−2×lcp(Ti,Tj)\sum_{i=1}^n \sum_{j=i ...

  4. bzoj 2882: 工艺【SAM】

    看上去比较SA,但是在学SAM所以就用SAM来做-- 把串复制一遍接在后面,对这个新串求SAM(这里的儿子节点要用map转移),然后从根节点每次都向最小的转移走,这样走n次转移的串就是答案 #incl ...

  5. 【SAM】loj#6401. 字符串

    网上有篇题解写的是线段树合并维护求值? 题目描述 有一个只包含小写字母,长度为 $n$ 的字符串 $S$ .有一些字母是好的,剩下的是坏的. 定义一个子串 $S_{l\ldots r}$是好的,当且仅 ...

  6. CF235C Cyclical Quest

    题意: 给出一个字符串s: n次询问某个字符串xi的循环同构串在s中出现多少次: |s|,∑|xi|<=10^6,n<=10^5: 题解: WJMZBMR场的SAM题... 感觉还没学多久 ...

  7. 2021牛客OI赛前集训营-提高组(第五场)D-牛牛的border【SAM】

    正题 题目链接:https://ac.nowcoder.com/acm/contest/20110/D 题目大意 求一个长度为nnn的字符串的所有子串的borderborderborder长度和. 1 ...

  8. P5546-[POI2000]公共串【SAM】

    正题 题面链接:https://www.luogu.com.cn/problem/P5546 题目大意 求nnn个串的最长公共子串. 解题思路 注意到最长公共子串一定是其中所有的子串,所以我们可以先随 ...

  9. P3181-[HAOI2016]找相同字符【SAM】

    正题 题目链接:https://www.luogu.com.cn/problem/P3181 题目大意 两个字符串,求有多少个(l1,r1,l2,r2)(l_1,r_1,l_2,r_2)(l1​,r1 ...

最新文章

  1. maya点线面计数_Maya课时:点线面体选择技巧视频教程_翼狐网
  2. npm 打包vue,错误 errno 126 / 清空node_modules目录
  3. 点击input框,添加阴影效果
  4. 前端学习(3187):ant-design的button介绍按钮属性
  5. git学习(6):删除github镜像
  6. JS-对象-构造函数-实例化-this
  7. Oracle JOB异常中断原因分析
  8. PXE-preboot execute environment
  9. 如何在C/C++中动态分配二维数组
  10. c++语言设计五子棋游戏,C++实现五子棋游戏
  11. linux服务器显卡监控脚本
  12. hazelcast java_JVM内存级分布式缓存Hazelcast
  13. linux下的触摸板关闭
  14. oracle 数据库网络传输,Oracle数据库之间数据传输方法探讨
  15. 流媒体-RTP/RTCP
  16. 制造工厂生产线液晶电子看板显示终端
  17. Arduino蜂鸣器与按键的结合
  18. macOS下长截图的两种方法
  19. 討厭現在的工作怎麼破?稻盛和夫:3個建議,讓你少走10年彎路
  20. 支付系统设计:绑卡、签约和身份验证(四)

热门文章

  1. java和python哪个学习编程_初学编程,选Java还是Python?
  2. python的所有库_Python 常用库
  3. linux文件读保护,Linux Rootkit实现文件保护
  4. linux创建备用管理员,sql server 创建备用管理员和只读用户
  5. 第jiu届蓝桥杯单片机省赛真题_第九届蓝桥杯单片机组省赛试题.pdf
  6. python数学计算_初学者Python学习笔记--数学计算
  7. Android开发p图软件,媲美大神P图效果 Android软件抠图神手
  8. 怎样用python批量处理文件夹_python批量处理文件或文件夹
  9. 读取oracle bfile字段,ORACLE中BFILE字段的使用研究_oracle
  10. 7-1 活动选择问题 (25 分)(思路+详解+扩展)宝 今天你AC了吗!!!