【字符串】模板

更新日志

  • 2018/10/4 绝大多数模板
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;

const int N=1000010;

char s1[N],s2[N];
int nxt[N];
int len1,len2;

void getnxt()
{
    for(int i=1,j=0;i<len2;i++)
    {
        while(s2[i]!=s2[j]&&j) j=nxt[j];
        if(s2[i]==s2[j]) nxt[i+1]=++j;
        else nxt[i+1]=0;
    }
    return;
}

int main()
{
    scanf("%s",s1);
    scanf("%s",s2);
    len1=strlen(s1);
    len2=strlen(s2);
    getnxt();
    
    for(int i=0,j=0;i<len1;i++)
    {
        while(s1[i]!=s2[j]&&j) j=nxt[j];
        if(s1[i]==s2[j]) j++;
        if(j==len2) printf("%d\n",i+2-len2);
    }
    
    for(int i=1;i<=len2;i++) printf("%d ",nxt[i]);
    return 0;
}
KMP字符串匹配
struct Trie
{
    int nxt[26];
    bool st;
    bool jud;
}T[500010];

char s[51];
int n,m,cnt=1;

namespace Trie_Tree
{
    void insert()
    {
        int rt=1;
        for(int i=0;s[i];i++)
        {
            int tmp=s[i]-'a';
            if(!T[rt].nxt[tmp])
            T[rt].nxt[tmp]=++cnt;
            rt=T[rt].nxt[tmp];
        }
        T[rt].jud=true;
        return;
    }
    
    int search()
    {
        int rt=1;
        for(int i=0;s[i];i++)
        {
            int tmp=s[i]-'a';
            if(!T[rt].nxt[tmp]) return 0;
            rt=T[rt].nxt[tmp];
        }
        if(!T[rt].jud) return 0;
        if(T[rt].st) return 2;
        T[rt].st=true; return 1;
    }
}
using namespace Trie_Tree;
Trie树
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;

const int N=1000010;

int n,len;
char s[N];

struct Trie
{
    int fail;
    int cnt;
    int nxt[26];
}T[N];

int cnt=0;

void insert()
{
    int rt=0;
    for(int i=0;i<len;i++)
    {
        int tmp=s[i]-'a';
        if(!T[rt].nxt[tmp])
        T[rt].nxt[tmp]=++cnt;
        rt=T[rt].nxt[tmp];
    }
    T[rt].cnt++;
    return;
}

void BFS()
{
    queue<int>q;
    for(int i=0;i<26;i++)
    {
        if(T[0].nxt[i])
        {
            T[T[0].nxt[i]].fail=0;
            q.push(T[0].nxt[i]);
        }
    }
    while(!q.empty())
    {
        int cur=q.front();
        q.pop();
        for(int i=0;i<26;i++)
        {
            if(T[cur].nxt[i])
            {
                T[T[cur].nxt[i]].fail=T[T[cur].fail].nxt[i];
                q.push(T[cur].nxt[i]);
            }
            else
            T[cur].nxt[i]=T[T[cur].fail].nxt[i];
        }
    }
}

int query()
{
    int rt=0,ans=0;
    for(int i=0;i<len;i++)
    {
        int tmp=s[i]-'a';
        rt=T[rt].nxt[tmp];
        for(int j=rt;j&&T[j].cnt!=-1;j=T[j].fail)
        {
            ans+=T[j].cnt;
            T[j].cnt=-1;
        }
    }
    return ans;
}

int main()
{
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",s);
        len=strlen(s);
        insert();
    }
    T[0].fail=0;
    BFS();
    scanf("%s",s);
    len=strlen(s);
    printf("%d\n",query());
    return 0;
}
AC自动机
#include<bits/stdc++.h>
#define N 51000010
using namespace std;

int len,p[N],ans=1;
char a[N],s[N<<1];

void manacher()
{
    int maxright=0,mid;
    for(int i=1;i<len;i++)
    {
        if(i<maxright)
        p[i]=min(p[mid]+mid-i,p[mid*2-i]);
        else p[i]=1;
        for(;s[i+p[i]]==s[i-p[i]];p[i]++);
        if(p[i]+i>maxright)
        {
            mid=i;
            maxright=mid+p[i];
        }
    }
}

void string_init()
{
    s[0]=s[1]='#';
    for(int i=0;i<len;i++)
    {
        s[i*2+2]=a[i];
        s[i*2+3]='#';
    }
    len=len*2+2;
    s[len]=0;
}

int main()
{
    scanf("%s",a);
    len=strlen(a);
    string_init();
    manacher();
    for(int i=0;i<len;i++)
    ans=max(ans,p[i]);
    ans--;
    printf("%d\n",ans);
    return 0;
}
Manacher算法
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;

const int N=300010;
long long ans;
int len,p,cnt=1;
char s[N];

namespace PAM
{
    struct node
    {
        int nxt[26];
        int fa,len,cnt;
    }T[N];
    
    void Extend(int x)
    {
        int tmp=s[x]-'a';
        while(s[x]!=s[x-T[p].len-1]) p=T[p].fa;
        if(!T[p].nxt[tmp])
        {
            int k=T[p].fa;
            T[++cnt].len=T[p].len+2;
            while(s[x]!=s[x-T[k].len-1]) k=T[k].fa;
            T[cnt].fa=T[k].nxt[tmp];
            T[p].nxt[tmp]=cnt;
        }
        p=T[p].nxt[tmp];
        T[p].cnt++;
    }
}
using namespace PAM;

int main()
{
    scanf("%s",s+1);
    len=strlen(s+1);
    T[0].fa=1;
    T[1].fa=1;
    T[0].len=0;
    T[1].len=-1;
    for (int i=1;i<=len;i++) Extend(i);
    for (int i=cnt;i>1;i--)
    {
        long long tmp=1LL*T[i].cnt*T[i].len;
        if(tmp>ans) ans=tmp;
        T[T[i].fa].cnt+=T[i].cnt;
    }
    return printf("%lld\n",ans),0;
}
回文自动机(PAM)
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;

const int N=1000010;
int SA[N],rank[N],height[N];
int x[N],y[N],bin[N];
int n,m=128;
char s[N];

void getSA()
{
    for(int i=1;i<=n;i++) bin[x[i]=s[i]-'0'+1]++;
    for(int i=1;i<=m;i++) bin[i]+=bin[i-1];
    for(int i=n;i>=1;i--) SA[bin[x[i]]--]=i;
    for(int k=1;k<=n;k<<=1)
    {
        int tmp=0;
        for(int i=n-k+1;i<=n;i++) y[++tmp]=i;
        for(int i=1;i<=n;i++) if(SA[i]>=k+1) y[++tmp]=SA[i]-k;
        for(int i=1;i<=m;i++) bin[i]=0;
        for(int i=1;i<=n;i++) bin[x[y[i]]]++;
        for(int i=1;i<=m;i++) bin[i]+=bin[i-1];
        for(int i=n;i>=1;i--) SA[bin[x[y[i]]]--]=y[i];
        swap(x,y);
        tmp=0;
        for(int i=1;i<=n;i++)
        {
            if(y[SA[i]]!=y[SA[i-1]]) x[SA[i]]=++tmp;
            else if(y[SA[i]+k]!=y[SA[i-1]+k]) x[SA[i]]=++tmp;
            else x[SA[i]]=tmp;
        }
        if(tmp>=n) break;
        m=tmp;
    }
    for(int i=1;i<=n;i++) rank[SA[i]]=i;
    for(int i=1,tmp=0;i<=n;i++)
    {
        if(tmp) --tmp;
        while(s[i+tmp]==s[SA[rank[i]-1]+tmp]) ++tmp;
        height[rank[i]]=tmp;
    }
}

int main()
{
    scanf("%s",s+1);
    n=strlen(s+1);
    getSA();
    for(int i=1;i<=n;i++) printf("%d ",SA[i]);
    return puts(""),0;
}
后缀数组
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;

const int MAXN=2000010;

long long ans=0;
char s[MAXN];
int a[MAXN],c[MAXN];
int len,size[MAXN];
int cnt=1,last=1;

struct SAM_node
{
    int nxt[26];
    int fa,len;
}T[MAXN<<1];

namespace SAM
{
    void insert(int x)
    {
        int cur=last,np=++cnt;
        last=np;
        T[np].len=T[cur].len+1;
        for(;cur&&!T[cur].nxt[x];cur=T[cur].fa)
        {
            T[cur].nxt[x]=np;
        }
        if(!cur)
        {
            T[np].fa=1;
        }
        else
        {
            int q=T[cur].nxt[x];
            if(T[cur].len+1==T[q].len)
            {
                T[np].fa=q;
            }
            else
            {
                int nq=++cnt;
                T[nq].len=T[cur].len+1;
                memcpy(T[nq].nxt,T[q].nxt,sizeof(T[q].nxt));
                T[nq].fa=T[q].fa;
                T[q].fa=T[np].fa=nq;
                for(;T[cur].nxt[x]==q;cur=T[cur].fa)
                {
                    T[cur].nxt[x]=nq;
                }
            }
        }
        size[np]=1;
    }
    
    void calc()
    {
        for(int i=1;i<=cnt;i++)
        {
            c[T[i].len]++;
        }
        for(int i=1;i<=cnt;i++)
        {
            c[i]+=c[i-1];
        }
        for(int i=1;i<=cnt;i++)
        {
            a[c[T[i].len]--]=i;
        }
        for(int i=cnt;i;i--)
        {
            int cur=a[i];
            size[T[cur].fa]+=size[cur];
            if(size[cur]>1)
            {
                ans=max(ans,1LL*size[cur]*T[cur].len);
            }
        }
        printf("%lld\n",ans);
        return;
    }
}
using namespace SAM;

int main()
{
    scanf("%s",s+1);
    len=strlen(s+1);
    for(int i=1;i<=len;i++)
    insert(s[i]-'a');
    calc();
    return 0;
}
后缀自动机(SAM)
int getmin()
{
    int i=0,j=1,k=0,t;
    while(i<len && j<len && k<len)
    {
        t=s[(i+k)%len]-s[(j+k)%len];
        if (!t) k++;
        else
        {
            if (t>0) i+=k+1; 
            else j+=k+1;
            if (i==j) j++;
            k=0;
        }
    }
    return min(i,j);
}
最小表示法
unsigned long long hash()
{
    int len=strlen(s);
    unsigned long long ans=0;
    for (int i=0;i<len;i++)
        ans=(ans*base+(unsigned long long)s[i])%mod;
    return ans;
}
哈希(Hash)

 

posted @ 2018-10-04 08:49  _ConveX  阅读(168)  评论(0编辑  收藏  举报