西安十五日游 day12 练习 【AC 自动机】

38 篇文章 0 订阅
6 篇文章 0 订阅

版子题

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 


#define MAXNode (1000000)
#define Sigma_size (26)
class Aho_Corasick_Automata
{
public:
    int ch[MAXNode][Sigma_size];
    int v[MAXNode],siz;
    // AC自动机 
    int f[MAXNode],last[MAXNode];
    Aho_Corasick_Automata(int _siz=0):siz(_siz){MEM(ch) MEM(v) MEM(f) MEM(last)}
    void mem(int _siz=0){siz=_siz; MEM(ch) MEM(v) MEM(f) MEM(last)  }
    int idx(char c){return c-'a';}
    void insert(char *s) //val不为0 表示str末尾 
    {
        int u=0,n=strlen(s);
        Rep(i,n)
        {
            int c=idx(s[i]);
            if (!ch[u][c])
            {
                ++siz;
                MEM(ch[siz]);
                ch[u][c]=siz;
            }
            u=ch[u][c];
        }
        v[u]++;
    }
    void getFail()
    {
        queue<int> q;
        Rep(c,Sigma_size)
        {
            int u=ch[0][c];
            if (u) q.push(u),last[u]=0;
        }
        while (!q.empty())
        {
            int r=q.front();q.pop();  //r--c-->u
            Rep(c,Sigma_size)
            {
                int u=ch[r][c];
                if (!u) {ch[r][c]=ch[f[r]][c]; continue;} 
                q.push(u);
                f[u]=ch[f[r]][c];
                last[u]=v[f[u]]?f[u]:last[f[u]];
            }
        }
    } 
    int ans;
    void print(int j) //打印全串中所有以j为末尾的str 
    {
        if (j)
        {
//          printf("%d %d\n",j,v[j]);
            ans+=v[j]; v[j]=0;
            print(last[j]);
        }
    } 
    void find(char *s)
    {
        int u=0,n=strlen(s);
        Rep(i,n)
        {
            int c=idx(s[i]);
            u=ch[u][c];
            if (v[u]) print(u);
            else if (last[u]) print(u);
        }
    }

}T;

char s[1000000+10];
int main()
{
//  freopen("A.in","r",stdin);
//  freopen(".out","w",stdout);
    int t=read();
    while(t--) {
        int n=read();
        T.mem();
        For(i,n) {
            scanf("%s",s);
            T.insert(s);
        }
        T.getFail();
        scanf("%s",s);
        T.ans=0;
        T.find(s);
        cout<<T.ans<<endl;
    }


    return 0;
}

病毒侵袭

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (500+10)
bool b[MAXN];

#define MAXNode (70000)
#define Sigma_size (100)
class Aho_Corasick_Automata
{
public:
    int ch[MAXNode][Sigma_size];
    int v[MAXNode],siz;
    // AC自动机 
    int f[MAXNode],last[MAXNode];
    Aho_Corasick_Automata(int _siz=0):siz(_siz){MEM(ch) MEM(v) MEM(f) MEM(last)}
    void mem(int _siz=0){siz=_siz; MEM(ch) MEM(v) MEM(f) MEM(last)  }
    int idx(char c){return c-31;}
    void insert(char *s,int val) //val不为0 表示str末尾 
    {
        int u=0,n=strlen(s);
        Rep(i,n)
        {
            int c=idx(s[i]);
            if (!ch[u][c])
            {
                ++siz;
                MEM(ch[siz]);
                ch[u][c]=siz;
            }
            u=ch[u][c];
        }
        v[u]=val;
    }
    void getFail()
    {
        queue<int> q;
        Rep(c,Sigma_size)
        {
            int u=ch[0][c];
            if (u) q.push(u),last[u]=0;
        }
        while (!q.empty())
        {
            int r=q.front();q.pop();  //r--c-->u
            Rep(c,Sigma_size)
            {
                int u=ch[r][c];
                if (!u) {ch[r][c]=ch[f[r]][c]; continue;} 
                q.push(u);
                f[u]=ch[f[r]][c];
                last[u]=v[f[u]]?f[u]:last[f[u]];
            }
        }
    } 
    void print(int j) //打印全串中所有以j为末尾的str 
    {
        if (j)
        {
            if (v[j]) {
                b[v[j]]=1; b[0]=1;
            }
            j=last[j];
        }
    } 
    void find(char *s)
    {
        int u=0,n=strlen(s);
        Rep(i,n)
        {
            int c=idx(s[i]);
            u=ch[u][c];
            if (v[u]) print(u);
            else if (last[u]) print(u);
        }
    }

}T;

char s[10000+10];
int n,m;
int main()
{
//  freopen("B.in","r",stdin);
//  freopen(".out","w",stdout);
//  cout<<sizeof(T)/1024<<endl;
    while(scanf("%d\n",&n)!=EOF) {
        T.mem();
        For(i,n) {
            gets(s);
            T.insert(s,i);
        }
        T.getFail();
        scanf("%d\n",&m);
        int tot=0;
        For(i,m) {
            gets(s);
            MEM(b)
            T.find(s);
            if(b[0]) {
                ++tot;
                printf("web %d:",i);
                For(i,n) if(b[i]) printf(" %d",i);
                puts("");
            }
        }
        printf("total: %d\n",tot);
    }


    return 0;
}

病毒侵袭持续中

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (1000+10)
int b[MAXN];

#define MAXNode (50010)
#define Sigma_size (26)
class Aho_Corasick_Automata
{
public:
    int ch[MAXNode][Sigma_size];
    int v[MAXNode],siz;
    // AC自动机 
    int f[MAXNode],last[MAXNode];
    Aho_Corasick_Automata(int _siz=0):siz(_siz){MEM(ch) MEM(v) MEM(f) MEM(last)}
    void mem(int _siz=0){siz=_siz; MEM(ch) MEM(v) MEM(f) MEM(last)  }
    int idx(char c){return c-'A';}
    void insert(char *s,int val) //val不为0 表示str末尾 
    {
        int u=0,n=strlen(s);
        Rep(i,n)
        {
            int c=idx(s[i]);
            if (!ch[u][c])
            {
                ++siz;
                MEM(ch[siz]);
                ch[u][c]=siz;
            }
            u=ch[u][c];
        }
        v[u]=val;
    }
    void getFail()
    {
        queue<int> q;
        Rep(c,Sigma_size)
        {
            int u=ch[0][c];
            if (u) q.push(u),last[u]=0;
        }
        while (!q.empty())
        {
            int r=q.front();q.pop();  //r--c-->u
            Rep(c,Sigma_size)
            {
                int u=ch[r][c];
                if (!u) {ch[r][c]=ch[f[r]][c]; continue;} 
                q.push(u);
                f[u]=ch[f[r]][c];
                last[u]=v[f[u]]?f[u]:last[f[u]];
            }
        }
    } 
    void print(int j) //打印全串中所有以j为末尾的str 
    {
        while (j)
        {
            if (v[j]) {
                b[v[j]]++;
            }
            j=last[j];
        }
    } 
    void find(char *s)
    {
        int u=0,n=strlen(s);
        Rep(i,n)
        {
            if (!isupper(s[i])) {
                u=0;continue;
            }
            int c=idx(s[i]);
            u=ch[u][c];
            if (v[u]) print(u);
            else if (last[u]) print(u);
        }
    }

}T;
char buf[MAXN][51];
char s[2000000+10];
int n,m;
int main()
{
//  freopen("C.in","r",stdin);
//  freopen(".out","w",stdout);
    while(scanf("%d\n",&n)!=EOF) {
        T.mem();
        For(i,n) {
            gets(buf[i]);
            T.insert(buf[i],i);
        }
        T.getFail();
        gets(s);
        MEM(b)
        T.find(s);
        For(i,n) if (b[i]) {
            printf("%s: %d\n",buf[i],b[i]);
        }
    }


    return 0;
}

Word Puzzles

把查找串作为模式串,记得反过来

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (1000+10)
int dir[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
int n,m,q;
bool inside(int i,int j){return 0<=i&&i<n&&0<=j&&j<m;}
int ans[MAXN][3];
char buf[MAXN][MAXN];
char s[MAXN+10];
#define MAXNode (5000000)
#define Sigma_size (26)
class Aho_Corasick_Automata
{
public:
    int ch[MAXNode][Sigma_size];
    int v[MAXNode],siz;
    // AC自动机 
    int f[MAXNode],last[MAXNode];
    Aho_Corasick_Automata(int _siz=0):siz(_siz){MEM(ch) MEM(v) MEM(f) MEM(last)}
    void mem(int _siz=0){siz=_siz; MEM(ch) MEM(v) MEM(f) MEM(last)  }
    int idx(char c){return c-'A';}
    void insert(char *s,int val) //val不为0 表示str末尾 
    {
        int u=0,n=strlen(s);
        Rep(i,n)
        {
            int c=idx(s[i]);
            if (!ch[u][c])
            {
                ++siz;
                MEM(ch[siz]);
                ch[u][c]=siz;
            }
            u=ch[u][c];
        }
        v[u]=val;
    }
    void getFail()
    {
        queue<int> q;
        Rep(c,Sigma_size)
        {
            int u=ch[0][c];
            if (u) q.push(u),last[u]=0;
        }
        while (!q.empty())
        {
            int r=q.front();q.pop();  //r--c-->u
            Rep(c,Sigma_size)
            {
                int u=ch[r][c];
                if (!u) {ch[r][c]=ch[f[r]][c]; continue;} 
                q.push(u);
                f[u]=ch[f[r]][c];
                last[u]=v[f[u]]?f[u]:last[f[u]];
            }
        }
    } 
    void print(int j,int x,int y,int k) //打印全串中所有以j为末尾的str 
    {
        while (j)
        {
            if (v[j]) {
                ans[v[j]][0]=x;
                ans[v[j]][1]=y;
                ans[v[j]][2]=k;
            }
            j=last[j];
        }
    } 
    void find(int x,int y,int k)
    {
        int u=0;
        while(inside(x,y))
        {
            char now=buf[x][y];
            int c=idx(now);
            u=ch[u][c];
            if (v[u]) print(u,x,y,k);
            else if (last[u]) print(u,x,y,k);
            x+=dir[k][0],y+=dir[k][1];
        }
    }

}T;
int main()
{
//  freopen("D.in","r",stdin);
//  freopen(".out","w",stdout);
    int t=read();
    For(kcase,t) {
        cin>>n>>m>>q;
        T.mem();
        Rep(i,n) {
            scanf("%s",buf[i]);
        }
        For(i,q) {
            scanf("%s",s);
            reverse(s,s+strlen(s));
            T.insert(s,i);
        }
        T.getFail();
        Rep(i,m) {
            T.find(n-1,i,0);
            T.find(n-1,i,1);
            T.find(n-1,i,7);
            T.find(0,i,3);
            T.find(0,i,4);
            T.find(0,i,5);
        }
        Rep(i,n) {
            T.find(i,0,1);
            T.find(i,0,2);
            T.find(i,0,3);
            T.find(i,m-1,5);
            T.find(i,m-1,6);
            T.find(i,m-1,7);
        }

        For(i,q) {
            if (ans[i][2]<4) ans[i][2]+=4; else ans[i][2]-=4;
            printf("%d %d %c\n",ans[i][0],ans[i][1],'A'+ans[i][2]);
        }
        if(kcase<t) puts("");
    }


    return 0;
}

考研路茫茫——单词情结

长度不超过L,只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个呢?
不包含的可以用AC自动机建立转移矩阵A,答案=A+A^2+A^3+..+A^L的第一行的和

#include<cstdio>
#include<iostream>
#include<functional>
#include<vector>
#include<cstring>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--))  
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define MAXN (100+10)
#define MAXNode (100+10)
#define Sigma_size (26)
#define pb push_back 
typedef unsigned long long ll;

ll pow2(ll a,ll b)
{
    if (b==1) return a;
    if (b==0) return 1;
    ll p=pow2(a,b/2);
    p=p*p;
    if (b&1) p=p*a;
    return p;
}

struct M  
{  
    int n,m;  
    ll a[MAXN][MAXN];  
    M(int _n=0){n=m=_n;MEM(a);} 
    M(int _n,int _m){n=_n,m=_m;MEM(a);}
    void mem (int _n=0){n=m=_n;MEM(a);}
    void mem (int _n,int _m){n=_n,m=_m;MEM(a);}

    friend M operator*(M a,M b)  
    {  
        M c(a.n,b.m);  
        For(k,a.m)
            For(i,a.n)  
                For(j,b.m)  
                    c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]);  
        return c;     
    }  
    friend M operator+(M a,M b)  
    {  
        For(i,a.n)  
            For(j,a.m)  
                a.a[i][j]=(a.a[i][j]+b.a[i][j]);  
        return a;
    }  
    void make_I(int _n)  
    {  
        n=m=_n; MEM(a)
        For(i,n) a[i][i]=1;  
    }  
}A;

bool a3[1000000];  
M pow222(M a,ll b)  
{  
    M c;c.make_I(a.n);    
    int n=0;while (b) a3[++n]=b&1,b>>=1;
    c=a; b=1;
    M d=c;
    ForD(i,n-1)    
    {    
        b=b*2+a3[i];
        c=c*d+c;
        d=d*d;
        if (a3[i]) c=c*a+a,d=d*a;
    }    
    return c;    
}
ll pow222(ll a,ll b)  
{  
    ll c=1;    
    int n=0;while (b) a3[++n]=b&1,b>>=1;
    c=a; b=1;
    ll d=c;
    ForD(i,n-1)    
    {    
        b=b*2+a3[i];
        c=c*d+c;
        d=d*d;
        if (a3[i]) c=c*a+a,d=d*a;
    }    
    return c;    
}

int n;
ll m;
class Trie
{
public:
    int ch[MAXNode][Sigma_size],fa[MAXNode];
    int fail[MAXNode],go[MAXNode][Sigma_size];
    int siz;
    bool tag[MAXNode];
    void mem(){siz=0; MEM(tag) MEM(ch) MEM(fa) MEM(go) MEM(fail) }
    int idx(char c){return c-'a';}
    void insert(char *s)
    {
        int u=0,n=strlen(s);
        Rep(i,n)
        {
            int c=idx(s[i]);
            if (!ch[u][c])
            {
                ++siz;
                MEM(ch[siz]);
                ch[u][c]=siz;
                fa[siz]=u;
            }
            u=ch[u][c];
        }
        tag[u]=1;
    }
    int q[MAXNode+10];
    void make_fail()
    {
        int Head=1,Tail=1;
        q[Head]=0;
        For(i,siz) fail[i]=0;
        while(Head<=Tail) {
            int u=q[Head];
            Rep(c,Sigma_size)
            {
                if (ch[u][c]) {
                    q[++Tail]=ch[u][c];
                    if (u==0) fail[ch[u][c]]=0;
                    else fail[ch[u][c]]=go[ fail[u] ][c];
                    go[u][c]=ch[u][c];
                }
                else {
                    go[u][c]=go[fail[u]][c];
                }
            } 
            Head++; 
        }
        For(i,Tail) {
            int now=q[i];
            if (tag[fail[now]]) tag[now]=1;
        }

        int t=0;
        vector<int> Q;
        int h[MAXN]={0};
        Rep(i,siz+1) {
            if (!tag[i]) Q.pb(i),h[i]=++t;
        }
        A.mem(t);
        For(i,t)
        {
            int now=Q[i-1]; 
            Rep(j,Sigma_size) {
                int v=go[now][j];
                if (h[v]) A.a[i][h[v]]++; 
            } 
        } 
    }
}T;

char s[20];
ll L; 
int main()
{
//  freopen("P.in","r",stdin);
//  freopen(".out","w",stdout);
    while(cin>>n>>L) {
        T.mem();
        For(i,n) {
            scanf("%s",s);
            T.insert(s);
        }
        T.make_fail();
        A=pow222(A,L);
        ll ans=0;
        ll tot=0;
        tot=pow222(Sigma_size,L);
        For(i,A.n) ans+=A.a[1][i];
        cout<<tot-ans<<endl;
    }
    return 0;
}

Resource Archiver

题意:design a 01 string that contains all your resources (their occurrences can overlap), but none of the virus codes. To make your software smaller in size, the string should be as short as possible.
对每个单机在AC自动机上bfs一遍,求它到每个节点的最短距离,然后跑TSP。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (1000+10)
int b[MAXN];
int n,m;
int pos[MAXN];
int g[MAXN][MAXN];
#define MAXNode (4000000)
#define Sigma_size (2)
class Aho_Corasick_Automata
{
public:
    int ch[MAXNode][Sigma_size];
    int v[MAXNode],siz;
    // AC自动机 
    int f[MAXNode],last[MAXNode];
    Aho_Corasick_Automata(int _siz=0):siz(_siz){MEM(ch) MEM(v) MEM(f) MEM(last)}
    void mem(int _siz=0){siz=_siz; MEM(ch) MEM(v) MEM(f) MEM(last)  }
    int idx(char c){return c-'0';}
    void insert(char *s,int val) //val不为0 表示str末尾 
    {
        int u=0,n=strlen(s);
        Rep(i,n)
        {
            int c=idx(s[i]);
            if (!ch[u][c])
            {
                ++siz;
                MEM(ch[siz]);
                ch[u][c]=siz;
            }
            u=ch[u][c];
        }
        v[u]=val;
        if (val!=-1) pos[val]=u; 
    }
    void getFail()
    {
        queue<int> q;
        Rep(c,Sigma_size)
        {
            int u=ch[0][c];
            if (u) q.push(u),last[u]=0;
        }
        while (!q.empty())
        {
            int r=q.front();q.pop();  //r--c-->u
            Rep(c,Sigma_size)
            {
                int u=ch[r][c];
                if (!u) {ch[r][c]=ch[f[r]][c]; continue;} 
                q.push(u);
                f[u]=ch[f[r]][c];
                last[u]=v[f[u]]?f[u]:last[f[u]];
            }
        }
    } 

    int dis[MAXNode];
    void bfs(int u) {
        queue<int> q;
        MEMI(dis) 
        q.push(pos[u]); dis[pos[u]]=0;
        while(!q.empty()) {
            int u=q.front(); q.pop();
            Rep(c,2) {
                if (dis[ch[u][c]]==INF&&v[ch[u][c]]!=-1) {
                    dis[ch[u][c]]=dis[u]+1;
                    q.push(ch[u][c]);
                }
            }
        }
        For(i,n) g[u][i]=dis[pos[i]];
    }

}T;
char s[100000+10];
int dp[1<<11][20],p2[20],len[20];
void work() {
    Rep(i,n) p2[i+1]=1<<i;
    int S=1<<n;
    MEMI(dp) 
    For(i,n) dp[p2[i]][i]=len[i];
    Rep(st,S) {
        For(i,n) {
            if (dp[st][i]!=INF) {
                For(j,n) if (!(st&p2[j])) {
                    int ne=st|p2[j];
                    if (g[i][j]==INF) continue; 
                    if (dp[ne][j]>dp[st][i]+g[i][j]) dp[ne][j]=dp[st][i]+g[i][j];
                }
            }
        }
    }
    int ans=INF;
    For(i,n) ans = min(ans, dp[S-1][i] );
    cout<<ans<<endl;
}
int main()
{
//  freopen("Q.in","r",stdin);
//  freopen(".out","w",stdout);
    while(scanf("%d%d\n",&n,&m)!=EOF&&n&&m) {
        T.mem();
        For(i,n) {
            scanf("%s",s); 
            T.insert(s,i);
            len[i]=strlen(s);
        }
        For(i,m) {
            scanf("%s",s); 
            T.insert(s,-1);
        }
        T.getFail();
        For(i,n) T.bfs(i);
        work();
    }


    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python AC自动机是一个用于字符串匹配的算法,它可以高效地在一段文本中查找多个预定义的模式。它的实现可以使用多种库,其中包括ac自动机python和ahocorasick-python。 ac自动机python是一个对标准的ac自动机算法进行了完善和优化的实现,适用于主流的Python发行版,包括Python2和Python3。它提供了更准确的结果,并且可以通过pip进行安装,具体的安装方法可以参考官方文档或者使用pip install命令进行安装。 ahocorasick-python是另一个实现AC自动机的库,它也可以用于Python2和Python3。你可以通过官方网站或者GitHub源码获取更多关于该库的信息和安装指南。 对于AC自动机的使用,一个常见的例子是在一段包含m个字符的文章中查找n个单词出现的次数。要了解AC自动机,需要有关于模式树(字典树)Trie和KMP模式匹配算法的基础知识。AC自动机的算法包括三个步骤:构造一棵Trie树,构造失败指针和模式匹配过程。在构造好AC自动机后,可以使用它来快速地在文本中查找预定义的模式,并统计它们的出现次数。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ahocorasick-python:AC自动机python的实现,并进行了优化。 主要修复了 查询不准确的问题](https://download.csdn.net/download/weixin_42122986/18825869)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Python实现多模匹配——AC自动机](https://blog.csdn.net/zichen_ziqi/article/details/104246446)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值