个人使用的一些模板

个人码风:大括号换行,4格缩进,轻微压行,行内空格极随意。

字符串

KMP

const int N=1000005;
char s[N], t[N];
int len_s, len_t, nxt[N];
void GetNext(char *s)
{
    for (int i=2, k=0; i<=len_s; i++)
    {
        while (k && s[i]!=s[k+1]) k=nxt[k];
        if (s[i]==s[k+1]) k++; nxt[i]=k;
    }
}

void KMP(char *s, char *t)
{
    for (int i=1, k=0; i<=len_t; i++)
    {
        while (k && t[i]!=s[k+1]) k=nxt[k];
        if (t[i]==s[k+1]) k++; 
        if (k==len_s){printf("%d\n", i-len_s+1); k=nxt[k];}
    }
}

SAM

inline void chkmax(int &x, int y){x<y?(x=y):0;}
inline void chkmin(int &x, int y){x>y?(x=y):0;}
const int N=1000005;
int son[N<<1][26], fa[N], len[N], last, cnt;//insert
int a[N], t[N], size[N];//sort
int mn[N], mx[N];//Get_N_LCS
int sum[N];//Get_Kth_Substr
char s[N];

namespace SuffixAutoMaton
{
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
        for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
        return x*f;
    }
    
    void insert(int c)
    {
        int p=last, np=last=++cnt; len[np]=len[p]+1;
        for (; p&&!son[p][c]; p=fa[p]) son[p][c]=np;
        if (!p) fa[np]=1;
        else
        {
            int q=son[p][c]; 
            if (len[p]+1==len[q]) fa[np]=q;
            else
            {
                int nq=++cnt; len[nq]=len[p]+1;
                memcpy(son[nq], son[q], sizeof(son[q]));
                fa[nq]=fa[q]; fa[q]=fa[np]=nq;
                for (; son[p][c]==q; p=fa[p]) son[p][c]=nq;
            }
        }
        size[np]=1;
    }
    
    void Sort()
    {
        for (int i=1; i<=cnt; i++) t[len[i]]++;
        for (int i=1; i<=cnt; i++) t[i]+=t[i-1];
        for (int i=1; i<=cnt; i++) a[t[len[i]]--]=i;
        for (int i=cnt; i; i--) size[fa[a[i]]]+=size[a[i]];
    }
    
    void build()
    {
        scanf("%s", s+1); last=cnt=1; int len=strlen(s+1);
        for (int i=1; i<=len; i++) insert(s[i]-'a');
    }
    
    void Get_LCS()
    {
        build(); scanf("%s", s+1); 
        int n=strlen(s+1), p=1, Len=0, ans=0;
        for (int i=1; i<=n; i++)
        {
            int c=s[i]-'a';
            if (son[p][c]) p=son[p][c], Len++;
            else
            {
                for (; p&&!son[p][c]; p=fa[p]);
                if (p) Len=len[p]+1, p=son[p][c];
                    else p=1, Len=0;
            }
            ans=max(ans, Len);
        }
        printf("%d\n", ans);
    }
    
    void Get_N_LCS()
    {
        memset(mn, 0x3f, sizeof(mn)); 
        build(); Sort(); int ans=0;
        while (~scanf("%s", s+1))
        {
            int n=strlen(s+1), p=1, Len=0;
            for (int i=1; i<=n; i++)
            {
                int c=s[i]-'a';
                if (son[p][c]) Len++, p=son[p][c], chkmax(mx[p], Len);
                else
                {
                    for (; p&&!son[p][c]; p=fa[p]);
                    if (p) Len=len[p]+1, p=son[p][c], chkmax(mx[p], Len);
                        else Len=0, p=1;
                }
            }
            for (int i=cnt; i; i--)
            {
                int u=a[i];
                chkmax(mx[fa[u]], min(mx[u], len[fa[u]]));
                chkmin(mn[u], mx[u]); mx[u]=0;
            }
        }
        for (int i=1; i<=cnt; i++) chkmax(ans, mn[i]);
        printf("%d\n", ans);
    }
    
    void Get_Kth_Dif_Substr()
    {
        Sort();
        for (int i=1; i<=cnt; i++) sum[i]=size[i]=1; sum[1]=size[1]=0;
        for (int i=cnt; i; i--) 
            for (int j=0; j<26; j++) sum[a[i]]+=sum[son[a[i]][j]];
        int k=read(), u=1; 
        if (sum[1]<k) {puts("-1"); exit(0);}
        while (k>0)
        {
            for (int i=0; i<26; i++) if (son[u][i])
            {
                if (sum[son[u][i]]<k) k-=sum[son[u][i]];
                    else{putchar(i+'a'); u=son[u][i]; k--; break;}
            }
        }
        puts("");
    }
    
    void Get_Kth_Substr()
    {
        Sort();
        for (int i=1; i<=cnt; i++) sum[i]=size[i]; sum[1]=size[1]=0;
        for (int i=cnt; i; i--) 
            for (int j=0; j<26; j++) sum[a[i]]+=sum[son[a[i]][j]];
        int k=read(), u=1; if (sum[1]<k) {puts("-1"); exit(0);}
        while (k>0)
        {
            for (int i=0; i<26; i++) if (son[u][i])
            {
                if (sum[son[u][i]]<k) k-=sum[son[u][i]];
                    else{putchar(i+'a'); u=son[u][i]; k-=size[u]; break;}
            }
        }
        puts("");
    }
}

SA

[待填坑]

AC自动机(Trie图)

const int N=1000005;
struct node{int fail, num, son[26];}t[N];
int cnt; char s[N];
namespace Aho_Corasick_Automaton
{
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
        for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
        return x*f;
    }
    
    void insert(char *s)
    {
        int len=strlen(s+1), p=0;
        for (int i=1; i<=len; i++)
        {
            int c=s[i]-'a';
            if (!t[p].son[c]) t[p].son[c]=++cnt;
            p=t[p].son[c];
        }
        t[p].num++;
    }
    
    void build_AC()
    {
        queue<int> q;
        for (int i=0; i<26; i++) if (t[0].son[i]) q.push(t[0].son[i]);
        while (!q.empty())
        {
            int now=q.front(), fail=t[now].fail; q.pop();
            for (int i=0; i<26; i++)
            {
                int son=t[now].son[i];
                if(son) t[son].fail=t[fail].son[i], q.push(son);
                    else t[now].son[i]=t[fail].son[i];
            }
        }
    }
    
    int find(char *s)
    {
        int len=strlen(s+1), pos=0, res=0;
        for (int i=1; i<=len; i++)
        {
            int c=s[i]-'a', now=pos=t[pos].son[c];
            while (now && t[now].num!=-1)
            {
                res+=t[now].num; t[now].num=-1;
                now=t[now].fail;
            }
        }
        return res;
    }
    
    void Build()
    {
        for (int i=1, n=read(); i<=n; i++) 
            scanf("%s", s+1), insert(s);
        build_AC();
    }
}

Manacher

const int N=11000005;
char t[N], s[N<<1]; int p[N<<1];
int main()
{
    scanf("%s", t+1); int n=strlen(t+1), ans=0;
    for (int i=1; i<=n; i++) s[i<<1]=t[i], s[i<<1|1]='#';
    (n<<=1)+=2; s[1]=s[n]='#';
    for (int i=1, maxr=0, mid=0; i<=n; i++)
    {
        p[i]=(i<maxr)?min(p[2*mid-i], p[mid]+mid-i):1;
        while (i+p[i]<=n && s[i+p[i]]==s[i-p[i]]) p[i]++;
        if (p[i]+i>maxr) maxr=p[i]+i, mid=i;
    }
    for (int i=1; i<=n; i++) ans=max(ans, p[i]-1);
    printf("%d\n", ans);
    return 0;
}

最小表示法

int main()
{
    int n=read(), k=0, i=0, j=1;
    for (int i=0; i<n; i++) a[i]=read();
    while (k<n && i<n && j<n)
    {
        if (a[(i+k)%n]==a[(j+k)%n]) k++;
        else 
        {
            a[(i+k)%n]>a[(j+k)%n]?i=i+k+1:j=j+k+1;
            i==j?i++:0; k=0;
        }
    } j=min(i, j);
    for (int i=j; i<n; i++) printf("%d ", a[i]);
    for (int i=0; i<j; i++) printf("%d ", a[i]); 
}

猜你喜欢

转载自www.cnblogs.com/ACMSN/p/10487023.html
今日推荐