Day7(字符串)

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