为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定义行为

马拉车

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. using namespace std;
  8. const int maxn=;
  9. int n,siz;
  10. char ch[maxn]={};
  11. char ch1[maxn*]={};
  12. int p[maxn*]={};
  13. void fir(){
  14. siz=n*+;
  15. ch1[]='$';ch1[]='#';
  16. for(int i=;i<=n;i++)ch1[i*]=ch[i-],ch1[i*+]='#';
  17. ch1[siz]='\0';
  18. }
  19. int Manacher(){
  20. fir();int x=,j=,ans=;
  21. for(int i=;i<siz;i++){
  22. if(x+j>i)p[i]=min(x+j-i+,p[x*-i]);
  23. else p[i]=;
  24. while(ch1[i+p[i]]==ch1[i-p[i]])p[i]++;
  25. if(i+p[i]->x+j)x=i,j=p[i]-;
  26. if(p[i]>ans)ans=p[i];
  27. //cout<<i<<ch1[i]<<p[i]<<endl;
  28. }
  29. return ans-;
  30. }
  31. int main(){
  32. int T;scanf("%d",&T);
  33. while(T-->){//ch[i],ch1[i],p[i]似乎都不用清空,因为所有的用之前都已经被清一次了。
  34. scanf("%s",ch);n=strlen(ch);
  35. int ma=Manacher();
  36. printf("%d\n",ma);
  37. }
  38. return ;
  39. }

Manacher

kmp

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. using namespace std;
  8. const int maxn=;
  9. int cn,sn;//模式串和主串的大小
  10. char ch[maxn]={};//模式串
  11. char st[maxn]={};//主串
  12. int nex[maxn]={};
  13. void kmp(){
  14. int j=-,i=;
  15. nex[]=-;
  16. while(i<cn){
  17. if(j==-||ch[i]==ch[j])nex[++i]=++j;
  18. else j=nex[j];
  19. }
  20. }
  21. int get_id(){//在主串中第一次出现的位置
  22. int i=,j=;
  23. while(i<sn&&j<cn){
  24. if(j==-||ch[j]==st[i]){i++;j++;}
  25. else j=nex[j];
  26. }
  27. if(j==cn)return i-cn;
  28. else return -;
  29. }
  30. int get_count(){//在主串中出现的次数
  31. int i,j=,cnt=;
  32. for(i=;i<sn;i++){
  33. while(j>&&st[i]!=ch[j]) j=nex[j];
  34. if(st[i]==ch[j])j++;
  35. if(j==cn){cnt++;j=nex[j];}
  36. }
  37. return cnt;
  38. }
  39. int main(){
  40. int T;scanf("%d",&T);
  41. while(T-->){
  42. scanf("%s",ch);cn=strlen(ch);
  43. scanf("%s",st);sn=strlen(st);
  44. kmp();
  45. printf("%d %d\n",get_id(),get_count());
  46. }
  47. return ;
  48. }

kmp

ac自动机(在poj2222提交的时候wa了好几次后来发现没有清空,而且这次重新打发现了自己之前写的漏洞。。。)

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. using namespace std;
  8. const int maxn=;
  9. int n,siz;
  10. char ch[]={};
  11. char str[maxn*]={};
  12. struct trie{
  13. int sig[];
  14. int cnt;
  15. int vis;
  16. int fail;
  17. }t[maxn*];int tot=;
  18. int q[maxn*]={};int head=,tail=;
  19. void fir(){
  20. tot=;memset(t,,sizeof(t));//memset(q,0,sizeof(q));
  21. }
  22. void init(int x,int j){
  23. if(j>siz-){ t[x].cnt++; return; }
  24. int z=ch[j]-'a';
  25. if(!t[x].sig[z])t[x].sig[z]=++tot;
  26. init(t[x].sig[z],j+);
  27. }
  28. void build_fail(){
  29. int head=,tail=,x,y,f;q[]=;
  30. while(head<=tail){
  31. x=q[head++];
  32. for(int i=;i<;i++)
  33. if(t[x].sig[i]){
  34. y=t[x].sig[i];
  35. if(x){
  36. f=t[x].fail;
  37. while((!t[f].sig[i])&&f)
  38. f=t[f].fail;
  39. t[y].fail=t[f].sig[i];
  40. }q[++tail]=y;
  41. }
  42. }
  43. }
  44. int get_num(){//字符串中包含的单词数量,重复的不记录,
  45. //如果单词x在字符串中出现一次而在单词表中有两个则ans+2
  46. //在字符串中出现两次而单词表中有一个则ans+1
  47. int ans=,x=,y,z;
  48. for(int i=;i<siz;i++){
  49. z=str[i]-'a';
  50. while((!t[x].sig[z])&&x)
  51. x=t[x].fail;
  52. x=t[x].sig[z];y=x;
  53. while(y&&(!t[y].vis)){//保证了每个结尾只访问一次
  54. ans+=t[y].cnt;
  55. t[y].vis=;t[y].cnt=;
  56. y=t[y].fail;
  57. }
  58. }
  59. return ans;
  60. }
  61. int main(){
  62. int T;scanf("%d",&T);
  63. while(T-->){
  64. fir();
  65. scanf("%d",&n);
  66. for(int i=;i<=n;i++){scanf("%s",ch);siz=strlen(ch);init(,);}
  67. build_fail();
  68. scanf("%s",str);siz=strlen(str);
  69. printf("%d\n",get_num());
  70. }
  71. return ;
  72. }

AC自动机

后缀数组 每次都l=<<2然后调错,我大概是个zz。一定要分清楚*2和<<1啊

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. using namespace std;
  8. const int maxn=;
  9. const int pl=;
  10. int siz;
  11. char ch[maxn+pl]={};
  12. int p[maxn+pl]={},sa[maxn+pl]={},rk[maxn+pl]={};
  13. int cnt[maxn+pl]={},temp[maxn+pl]={},height[maxn+pl]={};
  14. bool equ(int x,int y,int l){return rk[x]==rk[y]&&rk[x+l]==rk[y+l];}
  15. void SA(){
  16. for(int i=;i<=siz;i++)sa[i]=i,rk[i]=ch[i];
  17. for(int i,sig=,pos=,l=;pos<siz;sig=pos){
  18. pos=;
  19. for(i=siz-l+;i<=siz;i++)p[++pos]=i;
  20. for(i=;i<=siz;i++)if(sa[i]>l)p[++pos]=sa[i]-l;
  21. for(i=;i<=sig;i++)cnt[i]=;
  22. for(i=;i<=siz;i++)cnt[rk[p[i]]]++;
  23. for(i=;i<=sig;i++)cnt[i]+=cnt[i-];
  24. for(i=siz;i>;i--) sa[cnt[rk[p[i]]]--]=p[i];
  25. pos=;
  26. for(i=;i<=siz;i++){
  27. if(equ(sa[i],sa[i-],l))temp[sa[i]]=pos;
  28. else temp[sa[i]]=++pos;
  29. }
  30. for(i=;i<=siz;i++)rk[i]=temp[i];
  31. if(!l)l=;
  32. else l<<=;
  33. }
  34. int j=;
  35. for(int i=;i<=siz;i++){
  36. if(rk[i]==){j=;continue;}
  37. if(j)j--;
  38. while(ch[i+j]==ch[sa[rk[i]-]+j])j++;
  39. height[rk[i]]=j;
  40. }
  41. }
  42. int main(){
  43. scanf("%s",ch+);
  44. siz=strlen(ch+);
  45. SA();
  46. for(int i=;i<=siz;i++)printf("%d ",sa[i]);
  47. cout<<endl;
  48. for(int i=;i<=siz;i++)printf("%d ",height[i]);
  49. cout<<endl;
  50. return ;
  51. }

后缀数组

后缀自动机,相对于它的名气好写。但是有时候还是会在犯zz错误 这里的代码copy过来了

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<map>
  7. using namespace std;
  8. const int maxn=;
  9. char ch1[maxn]={},ch2[maxn]={};
  10. int siz1,siz2;
  11. struct nod{
  12. int sig[];
  13. int f,len;
  14. }t[maxn*];int tot=,la=;
  15. void add(int z){
  16. int x=++tot;int i=la;
  17. t[x].len=t[la].len+;
  18. for(;i&&!t[i].sig[z];i=t[i].f)
  19. t[i].sig[z]=x;
  20. if(!i)t[x].f=;
  21. else{
  22. int p=t[i].sig[z];
  23. if(t[p].len==t[i].len+)t[x].f=p;
  24. else{
  25. int y=++tot;
  26. t[y]=t[p];t[y].len=t[i].len+;
  27. t[x].f=t[p].f=y;
  28. for(;i&&t[i].sig[z]==p;i=t[i].f){
  29. t[i].sig[z]=y;
  30. }
  31. }
  32. }
  33. la=x;
  34. }
  35. int main(){
  36. memset(t,,sizeof(t));
  37. scanf("%s",ch1+);
  38. scanf("%s",ch2+);
  39. siz1=strlen(ch1+);
  40. siz2=strlen(ch2+);
  41. for(int i=;i<=siz1;i++)add(int(ch1[i]-'a'));
  42. int ans=,j=,tmp=;
  43. for(int i=;i<=siz2;i++){
  44. int z=ch2[i]-'a';
  45. if(t[j].sig[z]){j=t[j].sig[z];tmp++;}
  46. else{
  47. while(j&&!t[j].sig[z])
  48. j=t[j].f;
  49. if(!j){j=;tmp=;}
  50. else {tmp=t[j].len+;j=t[j].sig[z];}
  51. }
  52. if(tmp>ans)ans=tmp;
  53. }printf("%d\n",ans);
  54. return ;
  55. }

SAM

字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机的更多相关文章

  1. 【整理】如何选取后缀数组&&后缀自动机

    后缀家族已知成员         后缀树         后缀数组         后缀自动机         后缀仙人掌         后缀预言         后缀Splay ? 后缀树是后缀数 ...

  2. loj6173 Samjia和矩阵(后缀数组/后缀自动机)

    题目: https://loj.ac/problem/6173 分析: 考虑枚举宽度w,然后把宽度压位集中,将它们哈希 (这是w=2的时候) 然后可以写一下string=“ac#bc” 然后就是求这个 ...

  3. (17/34)AC自动机/后缀数组/后缀自动机(施工中)

    快补题别再摸鱼了(17/34) 1.AC自动机 #define maxnode 1000010 #define maxsize 26 struct ahocT{ int ch[maxnode][max ...

  4. POJ - 2774 Long Long Message (后缀数组/后缀自动机模板题)

    后缀数组: #include<cstdio> #include<algorithm> #include<cstring> #include<vector> ...

  5. luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分

    仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...

  6. SPOJ694 DISUBSTR --- 后缀数组 / 后缀自动机

    SPOJ694 DISUBSTR 题目描述: Given a string, we need to find the total number of its distinct substrings. ...

  7. POJ2774Long Long Message (后缀数组&后缀自动机)

    问题: The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to ...

  8. POJ1743 Musical Theme (后缀数组 & 后缀自动机)最大不重叠相似子串

    A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...

  9. SPOJ- Distinct Substrings(后缀数组&后缀自动机)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

随机推荐

  1. 【洛谷 P3648】 [APIO2014]序列分割 (斜率优化)

    题目链接 假设有\(3\)段\(a,b,c\) 先切\(ab\)和先切\(bc\)的价值分别为 \(a(b+c)+bc=ab+bc+ac\) \((a+b)c+ab=ab+bc+ac\) 归纳一下可以 ...

  2. js刷题:leecode 25

    原题:https://leetcode.com/problems/reverse-nodes-in-k-group/ 题意就是给你一个有序链表.如1->2->3->4->5,还 ...

  3. NYOJ 1272 表达式求值 第九届省赛 (字符串处理)

    title: 表达式求值 第九届省赛 nyoj 1272 tags: [栈,数据结构] 题目链接 描述 假设表达式定义为: 1. 一个十进制的正整数 X 是一个表达式. 2. 如果 X 和 Y 是 表 ...

  4. NYOJ 257 郁闷的C小加(一) (字符串处理)

    题目链接 描述 我们熟悉的表达式如a+b.a+b(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2.同理,后缀表达式就是操作符 ...

  5. Vue的keep-alive

    Vue的keep-alive: 简答的做下理解 缓存!页面从某一个页面跳转到另一个页面的时候,需要进行一定的缓存,然后这个时候调用的钩子函数是actived,而在第一次加载的时候,created.ac ...

  6. koa源码阅读[2]-koa-router

    koa源码阅读[2]-koa-router 第三篇,有关koa生态中比较重要的一个中间件:koa-router 第一篇:koa源码阅读-0第二篇:koa源码阅读-1-koa与koa-compose k ...

  7. three.js_sence(场景)

    1,THREE.Scene 的作用 (1)THREE.Scene 对象是所有不同对象的容器,也就是说该对象保存所有物体.光源.摄像机以及渲染所需的其他对象. (2)THREE.Scene 对象又是被称 ...

  8. 使用Burpsuite爆破弱口令教工号

    使用Burpsuite爆破弱口令教工号 发表于 2015-11-18   |   分类于 Burpsuite  |   1条评论  |   26次阅读 准备 所谓工欲善其事,必先利其器,首先当然是要下 ...

  9. python基础===基于cv2的播放器

    import cv2 import threading import win32gui,win32con class Producer(threading.Thread): ""& ...

  10. Python语言库pyttsx3

    这是一个文字转语音的python模块. 1. macos下安装的时候出现问题:  后来发现,Foundation, AppKit, PyObjCTools都不存在,主要原因是缺少依赖模块pyobjc, ...