题意:

给出一个字符串s;

n次询问某个字符串xi的循环同构串在s中出现多少次;

|s|,∑|xi|<=10^6,n<=10^5;

题解:

WJMZBMR场的SAM题。。。

感觉还没学多久的后缀自动机姿势已经忘光了。。。悲伤哦;

首先考虑如何查询一个xi串在s中出现了多少次,这个只要直接用s的后缀自动机的trans指针匹配,然后得到的结点的right值就是答案了;

那么一个串xi的所有循环同构串就是将其倍长之后,里面长度为|xi|的子串们;

答案就是在后缀自动机上匹配,每次在后面加一个字符再在前面减一个字符,累加right值;

在前面减字符这个过程不太容易实现,所以转化一下,变成在需要的时候延pre指针向上走一次;

具体来讲这个正确的原因就是pre指针组成了反向后缀树,那么这个延反向后缀树向上相当于减去了一些前缀(减去长度未必为1,所以要在需要的时候减去);

注意累加答案的时候,经过了一次的结点不能再计算一遍,直接跳过即可,匹配的长度不够的结点也不应累加进去;

时间复杂度大概是线性的吧= =

代码:

#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 2100000
#define S 26
using namespace std;
char s[N],str[N];
namespace SAM
{int son[N<<1][S],pre[N<<1],len[N<<1],right[N<<1],in[N<<1];int vis[N<<1];int last,tot;queue<int>q;int newnode(){return ++tot;}void init(){tot=0;last=newnode();}void Insert(int x){int np=newnode(),p;right[np]=1;len[np]=len[last]+1;for(p=last;p&&!son[p][x];p=pre[p])son[p][x]=np;if(!p)pre[np]=1;else{int q=son[p][x];if(len[q]==len[p]+1)pre[np]=q;else{int nq=newnode();len[nq]=len[p]+1;pre[nq]=pre[q];memcpy(son[nq],son[q],sizeof(int)*S);pre[q]=pre[np]=nq;for(;son[p][x]==q;p=pre[p])son[p][x]=nq;}}last=np;}void Build(){int x,i;for(i=1;i<=tot;i++)in[pre[i]]++;for(i=1;i<=tot;i++)if(!in[i])q.push(i);while(!q.empty()){x=q.front(),q.pop();right[pre[x]]+=right[x];in[pre[x]]--;if(!in[pre[x]])q.push(pre[x]);}}
}int main()
{int n,m,i,j,now,len,ans;scanf("%s",s+1);SAM::init();m=strlen(s+1);for(i=1;i<=m;i++)SAM::Insert(s[i]-'a');SAM::Build();scanf("%d",&n);for(i=1;i<=n;i++){scanf("%s",str+1);m=strlen(str+1);memcpy(str+m+1,str+1,sizeof(char)*m);for(j=1,ans=0,now=1,len=0;j<m+m;j++){while(now&&SAM::son[now][str[j]-'a']==0)now=SAM::pre[now],len=min(len,SAM::len[now]);if(!now)    now=1,len=0;elsenow=SAM::son[now][str[j]-'a'],len=min(len,SAM::len[now])+1;if(len>=m){while(SAM::len[SAM::pre[now]]>=m)now=SAM::pre[now],len=min(len,SAM::len[now]);if(len>=m&&SAM::vis[now]!=i)ans+=SAM::right[now],SAM::vis[now]=i;}}printf("%d\n",ans);}return 0;
}

CF235C Cyclical Quest相关推荐

  1. Codeforces 235C Cyclical Quest (后缀自动机)

    题目链接: https://codeforces.com/contest/235/problem/C 题解: 对大串建后缀自动机 对询问串复制拆环.这里一定要注意是复制一个循环节不是复制整个串!循环节 ...

  2. CodeForces 235C Cyclical Quest (后缀自动机)

    题意:给一个主串,再给出多个模式串,分别求主串中有多少个连续子串,与模式串循环同构. 题解:后缀自动机 因为要求循环同构,所以将模式串复制放到后面.(要么加终止符,要么传入长度) 先对主串建sam,然 ...

  3. Codeforces #235 C.Cyclical Quest(后缀自动机)

    传送门 题意:给定一个模式串和nnn个匹配串,询问原串有多少个子串和匹配串循环同构 考虑要求循环同构,于是先对SSS建出后缀自动机 把每次询问的XXX倍长在自动机上跑 如果当前匹配的长度已经超过原串长 ...

  4. 2020.6月做题记录

    长期计划 SAM专题 date:2020.05.21-2020.06.01 基础类: Problem Finished P3804 [模板]后缀自动机 (SAM) √√√ SP1811 LCS - L ...

  5. poj 1904 King's Quest

    King's Quest 题意:有N个王子和N个妹子;(1 <= N <= 2000)第i个王子喜欢Ki个妹子:(详见sample)题给一个完美匹配,即每一个王子和喜欢的一个妹子结婚:问每 ...

  6. 独家 | 使用深度神经网络在Oculus Quest上进行准确的手部追踪

    作者:Shangchen Han, Beibei Liu, Tsz Ho Yu, Randi Cabezas, Peizhao Zhang, Peter Vajda, Eldad Isaac, and ...

  7. Google Quest 冠军访谈:3个秘诀,8条建议,还有人在华为做 NLP 研究员

    导语:谷歌 QUEST Q&A 标签竞赛冠军方案. Anna Vander Stel 发布在 Unsplash 上的照片 近日,由 Google 举办的 Quest 问答标签大赛结果出炉,由 ...

  8. 阐述 QUEST CENTRAL FOR DB2 八罪

    作为一个从事oracle plsql发展2猿 - 年计划,现在,在退出DB2数据仓库项目. 同PL/SQL Developer参考,下文PLSQL,阐述QUEST CENTRAL FOR DB2 5. ...

  9. [XMAN2018排位赛]Dragon Quest [MRCTF2020]VirtualTree

    文章目录 [XMAN2018排位赛]Dragon Quest 拖入ida v5 = start_quest((std::string *)v7); sanitize_input(v6); 核心代码1 ...

最新文章

  1. 【收藏】Sentinel 高可用流量管理框架、服务熔断降级等
  2. Python中__new__和__init__的区别与联系
  3. java httpclient 关闭_【Java系列007】HttpClient调用:你考虑过关闭连接、并发了吗?...
  4. 你需要知道的基础算法知识——STL和基础数据结构(三)
  5. 案例学习BlazeDS+Spring之七InSync05新增联系人
  6. 15个Java的报表工具简介
  7. Unity调用iOS原生内购
  8. php 5.4连接mysql_MySQL数据库之PHP5.4中mysql连接
  9. [No0000105]java sdk 开发环境变量powershell 自动配置脚本
  10. kux格式 linux,怎么把1080P的kux视频转换成mp4呢
  11. 谷歌地图打不开怎么办?
  12. 做头条问答项目,月入4000元到底有多简单
  13. Javascript中LenB的计算(ASP)
  14. 一种安卓设备投屏到笔记本电脑上的简易方式
  15. Quality-Estimation1 (翻译质量评价-复现 WMT2018 阿里论文结果)
  16. 电力版 力控7.1 电力版 授权 硬件狗 USB加密狗 分享 下载
  17. 与北京相比较而言,杭州能不能挺进“一线”,还得看未来科技城---云城,第二机场入住云城周边是神助攻
  18. [BZOJ3653][长链剖分]谈笑风生
  19. 2020年哨兵数据批量下载(USGS)
  20. python把.CSV文件转换成.JSON格式文件并格式化储存

热门文章

  1. matlab与C语言混合编程
  2. mingw(msys2)编译ffmpeg
  3. matlab 向量 差分,MATLAB学习笔记(三)——数值计算
  4. Jpype 导入文件夹的所有jar包
  5. Unity简单工具使用----吃金币游戏(熟悉软件基本操作)
  6. 与国外有多少差距?浅谈国产游戏引擎进化论
  7. 计算机系初中毕业女生,又是一个女生,初中毕业 最好读什么职业学校?
  8. 传奇脚本显示服务器开区时间代码,上百种开区脚本代码详细介绍以及脚本示例...
  9. VC10如何在Release模式下调试代码
  10. 已知销售额怎么计算成本_知道销售金额,怎么计算成本,