热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【CodeForces235C】CyclicalQuest【后缀自动机】

题意给出一个字符串s1和q个询问,每个询问给出一个字符串s2,问这个询问的字符串的所有不同的周期串在s1中出现的次数的和。分析对于s1建后缀自动机。对于

题意

  给出一个字符串s1和q个询问,每个询问给出一个字符串s2,问这个询问的字符串的所有不同的周期串在s1中出现的次数的和。

分析

  对于s1建后缀自动机。对于询问的每个字符串s2,我们按照处理循环串的方法,将它长度乘二再复制一遍。然后根据s2在自动机上跑,当长度len=n的时候,就更新答案。因为要求统计的是不同的周期串,所以对于每个状态都需要打一个vis标记。

1 #include
2 #include
3 #include
4 #include
5
6 using namespace std;
7 const int maxn=2e6+10;
8 char s[maxn];
9 struct state{
10 int len,link;
11 int next[26];
12 }st[2*maxn];
13 int last,cur,sz,Q,n;
14 int cnt[2*maxn],c[2*maxn],vis[2*maxn];
15 void init(){
16 sz=1;
17 last=cur=0;
18 st[0].link=-1;
19 st[0].len=0;
20 }
21 void build_sam(int c){
22 cur=sz++;
23 st[cur].len=st[last].len+1;
24 cnt[cur]=1;
25 int p;
26 for(p=last;p!=-1&&st[p].next[c]==0;p=st[p].link){
27 st[p].next[c]=cur;
28 }
29 if(p==-1)
30 st[cur].link=0;
31 else{
32 int q=st[p].next[c];
33 if(st[q].len==st[p].len+1)
34 st[cur].link=q;
35 else{
36 int clone=sz++;
37 st[clone].len=st[p].len+1;
38 st[clone].link=st[q].link;
39 for(int i&#61;0;i<26;i&#43;&#43;)
40 st[clone].next[i]&#61;st[q].next[i];
41 for(;p!&#61;-1&&st[p].next[c]&#61;&#61;q;p&#61;st[p].link){
42 st[p].next[c]&#61;clone;
43 }
44 st[cur].link&#61;st[q].link&#61;clone;
45 }
46 }
47 last&#61;cur;
48 }
49 int cmp(int a,int b){
50 return st[a].len>st[b].len;
51 }
52 int solve(int id){
53 int res&#61;0;
54 int u&#61;0,len&#61;0;
55 for(int i&#61;0;i<2*n-1;i&#43;&#43;){
56 int c&#61;s[i]-&#39;a&#39;;
57 while(u!&#61;-1&&(st[u].next[c]&#61;&#61;0))
58 u&#61;st[u].link,len&#61;st[u].len;
59 if(u&#61;&#61;-1)
60 u&#61;0,len&#61;0;
61 else{
62 u&#61;st[u].next[c];
63 len&#43;&#43;;
64 if(len>&#61;n&&vis[u]!&#61;id){
65 res&#43;&#61;cnt[u];
66 vis[u]&#61;id;
67 }
68 while(n!&#61;1&&st[u].link!&#61;-1&&st[st[u].link].len>&#61;n-1)
69 u&#61;st[u].link,len&#61;st[u].len;
70 }
71 }
72 return res;
73 }
74
75 int main(){
76 scanf("%s",s);
77 n&#61;strlen(s);
78 init();
79 for(int i&#61;0;i)
80 build_sam(s[i]-&#39;a&#39;);
81 for(int i&#61;0;i)
82 c[i]&#61;i;
83 sort(c,c&#43;sz,cmp);
84 for(int i&#61;0;i){
85 int o&#61;c[i];
86 if(st[o].link!&#61;-1){
87 cnt[st[o].link]&#43;&#61;cnt[o];
88 }
89 }
90
91 scanf("%d",&Q);
92 for(int i&#61;1;i<&#61;Q;i&#43;&#43;){
93 // memset(vis,0,sizeof(vis));
94 scanf("%s",s);
95 n&#61;strlen(s);
96 for(int j&#61;0;j)
97 s[j&#43;n]&#61;s[j];
98 int res&#61;solve(i);
99 printf("%d\n",res);
100 }
101 return 0;
102 }

View Code

 

转:https://www.cnblogs.com/LQLlulu/p/9889594.html



推荐阅读
author-avatar
大囧囧不哭
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有