字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机
为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定义行为
马拉车
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<cmath>
- #include<queue>
- using namespace std;
- const int maxn=;
- int n,siz;
- char ch[maxn]={};
- char ch1[maxn*]={};
- int p[maxn*]={};
- void fir(){
- siz=n*+;
- ch1[]='$';ch1[]='#';
- for(int i=;i<=n;i++)ch1[i*]=ch[i-],ch1[i*+]='#';
- ch1[siz]='\0';
- }
- int Manacher(){
- fir();int x=,j=,ans=;
- for(int i=;i<siz;i++){
- if(x+j>i)p[i]=min(x+j-i+,p[x*-i]);
- else p[i]=;
- while(ch1[i+p[i]]==ch1[i-p[i]])p[i]++;
- if(i+p[i]->x+j)x=i,j=p[i]-;
- if(p[i]>ans)ans=p[i];
- //cout<<i<<ch1[i]<<p[i]<<endl;
- }
- return ans-;
- }
- int main(){
- int T;scanf("%d",&T);
- while(T-->){//ch[i],ch1[i],p[i]似乎都不用清空,因为所有的用之前都已经被清一次了。
- scanf("%s",ch);n=strlen(ch);
- int ma=Manacher();
- printf("%d\n",ma);
- }
- return ;
- }
Manacher
kmp
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<cmath>
- #include<queue>
- using namespace std;
- const int maxn=;
- int cn,sn;//模式串和主串的大小
- char ch[maxn]={};//模式串
- char st[maxn]={};//主串
- int nex[maxn]={};
- void kmp(){
- int j=-,i=;
- nex[]=-;
- while(i<cn){
- if(j==-||ch[i]==ch[j])nex[++i]=++j;
- else j=nex[j];
- }
- }
- int get_id(){//在主串中第一次出现的位置
- int i=,j=;
- while(i<sn&&j<cn){
- if(j==-||ch[j]==st[i]){i++;j++;}
- else j=nex[j];
- }
- if(j==cn)return i-cn;
- else return -;
- }
- int get_count(){//在主串中出现的次数
- int i,j=,cnt=;
- for(i=;i<sn;i++){
- while(j>&&st[i]!=ch[j]) j=nex[j];
- if(st[i]==ch[j])j++;
- if(j==cn){cnt++;j=nex[j];}
- }
- return cnt;
- }
- int main(){
- int T;scanf("%d",&T);
- while(T-->){
- scanf("%s",ch);cn=strlen(ch);
- scanf("%s",st);sn=strlen(st);
- kmp();
- printf("%d %d\n",get_id(),get_count());
- }
- return ;
- }
kmp
ac自动机(在poj2222提交的时候wa了好几次后来发现没有清空,而且这次重新打发现了自己之前写的漏洞。。。)
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<cmath>
- #include<queue>
- using namespace std;
- const int maxn=;
- int n,siz;
- char ch[]={};
- char str[maxn*]={};
- struct trie{
- int sig[];
- int cnt;
- int vis;
- int fail;
- }t[maxn*];int tot=;
- int q[maxn*]={};int head=,tail=;
- void fir(){
- tot=;memset(t,,sizeof(t));//memset(q,0,sizeof(q));
- }
- void init(int x,int j){
- if(j>siz-){ t[x].cnt++; return; }
- int z=ch[j]-'a';
- if(!t[x].sig[z])t[x].sig[z]=++tot;
- init(t[x].sig[z],j+);
- }
- void build_fail(){
- int head=,tail=,x,y,f;q[]=;
- while(head<=tail){
- x=q[head++];
- for(int i=;i<;i++)
- if(t[x].sig[i]){
- y=t[x].sig[i];
- if(x){
- f=t[x].fail;
- while((!t[f].sig[i])&&f)
- f=t[f].fail;
- t[y].fail=t[f].sig[i];
- }q[++tail]=y;
- }
- }
- }
- int get_num(){//字符串中包含的单词数量,重复的不记录,
- //如果单词x在字符串中出现一次而在单词表中有两个则ans+2
- //在字符串中出现两次而单词表中有一个则ans+1
- int ans=,x=,y,z;
- for(int i=;i<siz;i++){
- z=str[i]-'a';
- while((!t[x].sig[z])&&x)
- x=t[x].fail;
- x=t[x].sig[z];y=x;
- while(y&&(!t[y].vis)){//保证了每个结尾只访问一次
- ans+=t[y].cnt;
- t[y].vis=;t[y].cnt=;
- y=t[y].fail;
- }
- }
- return ans;
- }
- int main(){
- int T;scanf("%d",&T);
- while(T-->){
- fir();
- scanf("%d",&n);
- for(int i=;i<=n;i++){scanf("%s",ch);siz=strlen(ch);init(,);}
- build_fail();
- scanf("%s",str);siz=strlen(str);
- printf("%d\n",get_num());
- }
- return ;
- }
AC自动机
后缀数组 每次都l=<<2然后调错,我大概是个zz。一定要分清楚*2和<<1啊
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<cmath>
- #include<queue>
- using namespace std;
- const int maxn=;
- const int pl=;
- int siz;
- char ch[maxn+pl]={};
- int p[maxn+pl]={},sa[maxn+pl]={},rk[maxn+pl]={};
- int cnt[maxn+pl]={},temp[maxn+pl]={},height[maxn+pl]={};
- bool equ(int x,int y,int l){return rk[x]==rk[y]&&rk[x+l]==rk[y+l];}
- void SA(){
- for(int i=;i<=siz;i++)sa[i]=i,rk[i]=ch[i];
- for(int i,sig=,pos=,l=;pos<siz;sig=pos){
- pos=;
- for(i=siz-l+;i<=siz;i++)p[++pos]=i;
- for(i=;i<=siz;i++)if(sa[i]>l)p[++pos]=sa[i]-l;
- for(i=;i<=sig;i++)cnt[i]=;
- for(i=;i<=siz;i++)cnt[rk[p[i]]]++;
- for(i=;i<=sig;i++)cnt[i]+=cnt[i-];
- for(i=siz;i>;i--) sa[cnt[rk[p[i]]]--]=p[i];
- pos=;
- for(i=;i<=siz;i++){
- if(equ(sa[i],sa[i-],l))temp[sa[i]]=pos;
- else temp[sa[i]]=++pos;
- }
- for(i=;i<=siz;i++)rk[i]=temp[i];
- if(!l)l=;
- else l<<=;
- }
- int j=;
- for(int i=;i<=siz;i++){
- if(rk[i]==){j=;continue;}
- if(j)j--;
- while(ch[i+j]==ch[sa[rk[i]-]+j])j++;
- height[rk[i]]=j;
- }
- }
- int main(){
- scanf("%s",ch+);
- siz=strlen(ch+);
- SA();
- for(int i=;i<=siz;i++)printf("%d ",sa[i]);
- cout<<endl;
- for(int i=;i<=siz;i++)printf("%d ",height[i]);
- cout<<endl;
- return ;
- }
后缀数组
后缀自动机,相对于它的名气好写。但是有时候还是会在犯zz错误 这里的代码copy过来了
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<cmath>
- #include<map>
- using namespace std;
- const int maxn=;
- char ch1[maxn]={},ch2[maxn]={};
- int siz1,siz2;
- struct nod{
- int sig[];
- int f,len;
- }t[maxn*];int tot=,la=;
- void add(int z){
- int x=++tot;int i=la;
- t[x].len=t[la].len+;
- for(;i&&!t[i].sig[z];i=t[i].f)
- t[i].sig[z]=x;
- if(!i)t[x].f=;
- else{
- int p=t[i].sig[z];
- if(t[p].len==t[i].len+)t[x].f=p;
- else{
- int y=++tot;
- t[y]=t[p];t[y].len=t[i].len+;
- t[x].f=t[p].f=y;
- for(;i&&t[i].sig[z]==p;i=t[i].f){
- t[i].sig[z]=y;
- }
- }
- }
- la=x;
- }
- int main(){
- memset(t,,sizeof(t));
- scanf("%s",ch1+);
- scanf("%s",ch2+);
- siz1=strlen(ch1+);
- siz2=strlen(ch2+);
- for(int i=;i<=siz1;i++)add(int(ch1[i]-'a'));
- int ans=,j=,tmp=;
- for(int i=;i<=siz2;i++){
- int z=ch2[i]-'a';
- if(t[j].sig[z]){j=t[j].sig[z];tmp++;}
- else{
- while(j&&!t[j].sig[z])
- j=t[j].f;
- if(!j){j=;tmp=;}
- else {tmp=t[j].len+;j=t[j].sig[z];}
- }
- if(tmp>ans)ans=tmp;
- }printf("%d\n",ans);
- return ;
- }
SAM
字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机的更多相关文章
- 【整理】如何选取后缀数组&&后缀自动机
后缀家族已知成员 后缀树 后缀数组 后缀自动机 后缀仙人掌 后缀预言 后缀Splay ? 后缀树是后缀数 ...
- loj6173 Samjia和矩阵(后缀数组/后缀自动机)
题目: https://loj.ac/problem/6173 分析: 考虑枚举宽度w,然后把宽度压位集中,将它们哈希 (这是w=2的时候) 然后可以写一下string=“ac#bc” 然后就是求这个 ...
- (17/34)AC自动机/后缀数组/后缀自动机(施工中)
快补题别再摸鱼了(17/34) 1.AC自动机 #define maxnode 1000010 #define maxsize 26 struct ahocT{ int ch[maxnode][max ...
- POJ - 2774 Long Long Message (后缀数组/后缀自动机模板题)
后缀数组: #include<cstdio> #include<algorithm> #include<cstring> #include<vector> ...
- luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分
仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...
- SPOJ694 DISUBSTR --- 后缀数组 / 后缀自动机
SPOJ694 DISUBSTR 题目描述: Given a string, we need to find the total number of its distinct substrings. ...
- POJ2774Long Long Message (后缀数组&后缀自动机)
问题: The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to ...
- POJ1743 Musical Theme (后缀数组 & 后缀自动机)最大不重叠相似子串
A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...
- SPOJ- Distinct Substrings(后缀数组&后缀自动机)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
随机推荐
- 【洛谷 P3648】 [APIO2014]序列分割 (斜率优化)
题目链接 假设有\(3\)段\(a,b,c\) 先切\(ab\)和先切\(bc\)的价值分别为 \(a(b+c)+bc=ab+bc+ac\) \((a+b)c+ab=ab+bc+ac\) 归纳一下可以 ...
- js刷题:leecode 25
原题:https://leetcode.com/problems/reverse-nodes-in-k-group/ 题意就是给你一个有序链表.如1->2->3->4->5,还 ...
- NYOJ 1272 表达式求值 第九届省赛 (字符串处理)
title: 表达式求值 第九届省赛 nyoj 1272 tags: [栈,数据结构] 题目链接 描述 假设表达式定义为: 1. 一个十进制的正整数 X 是一个表达式. 2. 如果 X 和 Y 是 表 ...
- NYOJ 257 郁闷的C小加(一) (字符串处理)
题目链接 描述 我们熟悉的表达式如a+b.a+b(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2.同理,后缀表达式就是操作符 ...
- Vue的keep-alive
Vue的keep-alive: 简答的做下理解 缓存!页面从某一个页面跳转到另一个页面的时候,需要进行一定的缓存,然后这个时候调用的钩子函数是actived,而在第一次加载的时候,created.ac ...
- koa源码阅读[2]-koa-router
koa源码阅读[2]-koa-router 第三篇,有关koa生态中比较重要的一个中间件:koa-router 第一篇:koa源码阅读-0第二篇:koa源码阅读-1-koa与koa-compose k ...
- three.js_sence(场景)
1,THREE.Scene 的作用 (1)THREE.Scene 对象是所有不同对象的容器,也就是说该对象保存所有物体.光源.摄像机以及渲染所需的其他对象. (2)THREE.Scene 对象又是被称 ...
- 使用Burpsuite爆破弱口令教工号
使用Burpsuite爆破弱口令教工号 发表于 2015-11-18 | 分类于 Burpsuite | 1条评论 | 26次阅读 准备 所谓工欲善其事,必先利其器,首先当然是要下 ...
- python基础===基于cv2的播放器
import cv2 import threading import win32gui,win32con class Producer(threading.Thread): ""& ...
- Python语言库pyttsx3
这是一个文字转语音的python模块. 1. macos下安装的时候出现问题: 后来发现,Foundation, AppKit, PyObjCTools都不存在,主要原因是缺少依赖模块pyobjc, ...