字符串

哈希

typedef unsigned long long ULL;
const int N = 1000010, P = 131;
int n, m;
string s;

ULL p[N], h[N];

void init(){
    p[0] = 1, h[0] = 0;
    string pys = "#" + s;
    for(int i = 1; i <= n; i ++){
        p[i] = p[i-1] * P;
        h[i] = h[i-1] * P + s[i];
    }     
}

ULL get(int l, int r) {
    return h[r] - h[l-1] * p[r-l+1];
}

bool substrequal(int l1, int r1, int l2, int r2) {
    return get(l1, r1) == get(l2, r2);
}

字典树

constexpr int maxn = 500010;
constexpr int charsize = 26;

struct TreeNode{
    int nxt[charsize];
    bool isend;
}tree[maxn + 1];

int root = 0, cnt = 0;

void insert(string s){
    int now = 0, len = s.size();
    for(int i = 0; i < len; i++){
        int x = s[i] - 'a';
        if (!tree[now].nxt[x]) {
            tree[now].nxt[x] = ++cnt;
        }
        now = tree[now].nxt[x];
    }
    tree[now].isend = 1;
}

bool search(string s){
    int now=0, len = s.size();
    for(int i = 0; i < len; i++){
        int x = s[i] - 'a';
        if(!tree[now].nxt[x]){
            return false;
        }
        now = tree[now].nxt[x];
    }
    return tree[now].isend;
}

kmp

const int N=100010,M=100010;
int nxt[M+1],f[N+1];
string s,p;
void kmp(){
    int n=s.size(),m=p.size();
    s="#"+s;p="#"+p;
    int j=0;nxt[1]=0;
    for(int i=2;i<=m;i++){
        while(j>0&&p[j+1]!=p[i])
            j=nxt[j];
        if(p[j+1]==p[i]){
            j++;
        }
        nxt[i]=j;
    }
    j=0;
    for(int i=1;i<=n;i++){
        while((j==m)||(j>0&&p[j+1]!=s[i])){
            j=nxt[j];
        }
        if(p[j+1]==s[i]){
            j++;
        }
        f[i]=j;
    }
}

exkmp

vector<int> Z(string s){
    vector<int> z((int)s.size()+1);
    int L=1,R=0,n=s.size();
    s="#"+s;
    z[1]=0;
    for(int i=2;i<=n;i++){
        if(i>R){
            z[i]=0;
        }else{    
            int k=i-L+1;
            z[i]=min(z[k],R-i+1);
        }
        while(i+z[i]<=n&&(s[z[i]+1]==s[i+z[i]])){
            z[i]++;
        }
        if(i+z[i]-1>R){
            L=i,R=i+z[i]-1;
        }
    }
    return z;
}

最小表示法

string getmin(string s) {
    int n = s.size();
    s += s; s = "#" + s;
    int i = 1, j = 2;
    while (j <= n) {
        int k = 0;
        while (k < n && s[i + k] == s[j + k]) {
            ++k;
        }
        if (s[i + k] > s[j + k]) {
            i += k + 1;
        } else {
            j += k + 1;
        }
        if (i == j) j++;
        if (i > j) swap(i, j);
    }
    string res = "";
    for (int l = i; l <= i + n - 1; l ++) {
        res.push_back(s[l]);
    }
    return res;
}

AC自动机

constexpr int M = 26, N = 1000010;
struct node{
    node *son[M], *go[M], *fail;
    int cnt;
}pool[N], *cur = pool, *root, *d[210];

node *newnode() {
    return cur++;
}

int t;
node *q[N];

void build() {
    t = 0;
    q[t++] = root;
    for (int i = 0; i < t; i++) {
        node *u = q[i];
        for (int j = 0; j < M; j++) {
            if (u->son[j]) {
                u->go[j] = u->son[j];
                if (u == root) u->son[j]->fail = root;
                else u->son[j]->fail = u->fail->go[j];
                q[t++] = u->son[j];
            } else {
                if (u == root) u->go[j] = root;
                else u->go[j] = u->fail->go[j];
            }
        }
    }
}
/*
root = newnode();
for(c : s) int w = c - 'a' if(!p->son[w]) p->son[w]=newnode; p=p->son[w]; 
*/

manacher

const int N=100010;
int n,p[2*N+2];
char s[N+2],t[2*N+2];

void manacher(){
    n=strlen(s+1);
    int m=0;
    t[++m]='#';
    for(int i=1;i<=n;i++){
        t[++m]=s[i],t[++m]='#';
    }
    int M=0,R=0;
    for(int i=1;i<=m;i++){
        if(i>R){
            p[i]=1;
        }else{
            p[i]=min(p[2*M-i],R-i+1);
        }
        while(i-p[i]>0&&i+p[i]<=m&&t[i-p[i]]==t[i+p[i]])
            ++p[i];
        if(i+p[i]-1>R){
            M=i,R=i+p[i]-1;
        }
    }
    int ans=0;
    for(int i=1;i<=m;i++){
        ans=max(ans,p[i]);
    }
    cout<<ans-1;

}

 

posted @ 2024-03-21 19:56  Miburo  阅读(6)  评论(0)    收藏  举报