Day7(字符串)

it2022-05-09  23

strlen(s) O(n)

 

Trie树 

O(sigma len[i]);

 

AC自动机

建立一个trie树

fail指针:根的fail指针指向自己,其余节点找到一个最长后缀使得它是原来某个串的一个前缀,fail指针指向该前缀在trie树上的位置

fail指针性质:1.指向比它浅的节点(除根的fail指针外)

                       2.所有的fail指针组成的是一棵树fail树(除根的fail指针外:n个点,n-1条边,无环)

匹配:按位匹配,若不能向下匹配则沿fail指针向上跳,直到可向下匹配或走到根

O(M) (原因:由于每匹配一位最多向下跳一次,共最多向下跳M次,故最多向上跳M次)

 

一种用来理解的代码:

inline void build_AC(){//bfs queue<int>q; q.push(rt); while(!q.empty()){ int x=q.front();q.pop(); for(int a=0;a<size;a++){//size 有多少个儿子 if(z[now].next[a]){ //now这个节点有没有a这个儿子 int p=z[now].fail; while(p){ if(z[p].next[a]){ z[z[now].next[a]].fail=z[p].next[a]; break; } p=z[p].fail; } if(!p) z[z[now].next[a]].fail=rt; q.push(z[now].next[a]); }else{//补齐:匹配时不用分类向上跳,直接沿着next走就好了 z[now].next[a]=z[z[now].fail].next[a]; if(!z[now].next[a]) z[now].next[a]=rt; } } } } View Code

 

 后缀数组

把n个后缀排序

rankk[i]表示从每个位置开始排k个字符,i排在第几名

rank2[i] - > rank4[i] - > rank8[i] - > …… -  > rank 2^k [i] 

基数排序:O(2n)

struct node{ int pos,x[2];//pos开始的位置是哪里,x[0]与x[1]存储用来基数排序的两个值 node(){} node(int a,int b,int c){ pos=a;x[1]=b;x[0]=c; } }x[maxn],sw[maxn]; inline void count_sort(int upper){ for(int a=0;a<=1;a++){ memset(buf,0,sizeof(buf)); for(int b=1;b<=n;b++) buf[x[b].x[a]]++; for(int b=1;b<=upper;b++) inline void sa(){ for(int a=1;a<=n;a++) x[a]=node(a,z[a],0); count_sort(n);//得到所有rank1[i] for(int a=1;a<=n;a<<=1){ for(int b=1;b<=n;b++) x[b]=node(b,rank[b],a+b<=n?rank[a+b]:0); count_sort(n); }//rank[i]第i个后缀排名第几 for(int a=1;a<=n;a++) sa[rank[a]]=a;//sa[i]排名为i的后缀是第几个后缀 } View Code

height数组

height[i]表示排名为i的后缀和排名为i-1的后缀的最长公共前缀长度

应用:求任意两个后缀的最长公共前缀 - > height数组区间最小值

 

Manacher算法--对称

()()不是回文串23333~~

求以每一个位置为中心的最长回文串长度,均为奇数

在中间插字符,得到偶数长度回文串

https://www.luogu.org/problemnew/show/P3805

https://www.luogu.org/problemnew/show/P4287

 

Z-Box(扩展KMP算法)--平移

求每一个后缀与原串的最长公共前缀

f[1]=l

f[2]=

求f[i],设f[1]---f[i-1]已经求完了,找到右端点最靠右的一串,设起点为p,终点为r

f[i]=min(r-i+1,f[i-p+1])

 

Hash

自然溢出:mod 2^64 unsigned long long

单模:1个10^9左右的质数(容易被卡)

双模:2个10^9左右的质数(会被卡常)

 

DFA

确定状态自动机--有向图,一个起始点,多少个终结点??

从一个点出发的边不能有字母相同的

 

NFA

不确定状态自动机--有向图,一个起始点,任意多个终结点

从一个点出发的边可以有字母相同的

转载于:https://www.cnblogs.com/wifimonster/p/10231414.html


最新回复(0)