poj2778&&bzoj1030

本文介绍了一种使用AC自动机和矩阵快速幂解决字符串匹配问题的方法。具体包括AC自动机的构建过程、矩阵快速幂的应用场景以及如何将二者结合解决特定问题。通过实例演示了如何插入模式串构建AC自动机,再利用矩阵快速幂加速计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<set>
using namespace std;
typedef long long ll;
const int maxt=105;
const int mod=100000;
int n,m;
int tot;
char a[105];
struct aho
{
   int cnt;
   int fail[maxt],to[maxt][5];
   bool danger[maxt];
   int q[maxt];
   aho()
   {
      cnt=1;
      fail[1]=0;
      for(int i=1;i<=4;i++)
      {
          to[0][i]=1;
      }
   }
   int idx(char k)
   {
       if(k=='A') return 1;
       if(k=='T') return 2;
       if(k=='C') return 3;
       if(k=='G') return 4;
   }
   void insert(char *s)
   {
       int n=strlen(s+1);
       int now=1;
       for(int i=1;i<=n;i++)
       {
           int c=idx(s[i]);
           if(to[now][c]) now=to[now][c];
           else
           {
               to[now][c]=++cnt;
               now=to[now][c];
           }
       }
       danger[now]=1;
   }
   void build()
   {
       int head=0,tail=1;
       q[0]=1;
       while(head<tail)
       {
           int k=q[head++];
           for(int i=1;i<=4;i++)
           {
               if(to[k][i])
               {
                   int tmp=fail[k];
                   while(!to[tmp][i]) tmp=fail[tmp];
                   fail[to[k][i]]=to[tmp][i];
                   if(danger[to[tmp][i]])danger[to[k][i]]=1;
                   q[tail++]=to[k][i];
               }
           }
       }
   }
}T;
struct M
{
    ll v[maxt][maxt];
    M()
    {
        memset(v,0,sizeof(v));
    }
    friend M operator *(M a,M b)
    {
        M c;
        for(int i=1;i<=tot;i++)
        {
            for(int j=1;j<=tot;j++)
            {
                for(int k=1;k<=tot;k++)
                {
                    c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j])%mod;
                }
            }
        }
        return c;
    }
    friend M operator ^(M a,int k)
    {
        M c;
        for(int i=1;i<=tot;i++)
        {
            c.v[i][i]=1;
        }
        for(int i=k;i;i>>=1,a=a*a)
        {
            if(i&1) c=c*a;
        }
        return c;
    }
     void printt(M a)
    {
        for(int i=1;i<=tot;i++)
        {
            for(int j=1;j<=tot;j++)
                printf("%lld ",a.v[i][j]);
            printf("\n");
        }
    }
}b;

void solve()
{
    tot=T.cnt;
   // cout<<tot<<endl;
    for(int i=1;i<=tot;i++)
    {
        if(T.danger[i]) continue;
        for(int j=1;j<=4;j++)
        {
            int tmp=i;
            while(!T.to[tmp][j])tmp=T.fail[tmp];
            if(!T.danger[T.to[tmp][j]])b.v[T.to[tmp][j]][i]++;
        }
    }
   // b.printt(b);
    M ans;
    ans.v[1][1]=1;
    ans=(b^n)*ans;
    ll res=0;
    for(int i=1;i<=tot;i++)
    {
        res=(res+ans.v[i][1])%mod;
    }
    printf("%lld\n",res);
}
int main()
{
    // char a[105];
     scanf("%d%d",&m,&n);
     for(int i=1;i<=m;i++)
     {
         scanf("%s",a+1);
         T.insert(a);
     }
     T.build();
     solve();
     return 0;

}


#include<bits/stdc++.h>
using namespace std;
const int maxn=6007;
const int mod=10007;
int n,m;
int sz=1,ans1,ans2=1;
int a[maxn][27],failptr[maxn];
int f[107][maxn];
char s[107];
int que[maxn];
bool danger[maxn];
void ins()
{
    int now=1,c;
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        c=s[i]-'A'+1;
        if(a[now][c])now=a[now][c];
        else
        {
            a[now][c]=++sz;
            now=a[now][c];
        }
    }
    danger[now]=1;
}
void acmach()
{
    int head=0,tail=1;
    int now;
    que[0]=1;
    failptr[1]=0;
    while(head<tail)
    {
        now=que[head++];
        for(int i=1;i<=26;i++)
        {
            if(!a[now][i]) continue;
            int tmp=failptr[now];
            while(!a[tmp][i]) tmp=failptr[tmp];
            failptr[a[now][i]]=a[tmp][i];
            if(danger[a[tmp][i]]) danger[a[now][i]]=1;
            que[tail++]=a[now][i];
        }
    }
}
void dp(int k)
{
    for(int i=1;i<=sz;i++)
    {
        if(danger[i]||!f[k-1][i]) continue;
        for(int j=1;j<=26;j++)
        {
            int tmp=i;
            while(!a[tmp][j]) tmp=failptr[tmp];
            f[k][a[tmp][j]]=(f[k][a[tmp][j]]+f[k-1][i])%mod;
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=26;i++)a[0][i]=1;//OMG
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);
        ins();
    }
  //  cout<<111<<endl;
    acmach();
  //  printf("444");
    f[0][1]=1;
    for(int i=1;i<=m;i++)dp(i);
    for(int i=1;i<=m;i++)
        ans2=(ans2*26)%mod;
    for(int i=1;i<=sz;i++)
    {
        if(!danger[i]) ans1=(ans1+f[m][i])%mod;
    }
   // cout<<ans1<<endl;
    printf("%d",(ans2-ans1+mod)%mod);
}

资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 华为移动服务(Huawei Mobile Services,简称 HMS)是一个全面开放的移动服务生态系统,为企业和开发者提供了丰富的工具和 API,助力他们构建、运营和推广应用。其中,HMS Scankit 是华为推出的一款扫描服务 SDK,支持快速集成到安卓应用中,能够提供高效且稳定的二维码和条形码扫描功能,适用于商品扫码、支付验证、信息获取等多种场景。 集成 HMS Scankit SDK 主要包括以下步骤:首先,在项目的 build.gradle 文件中添加 HMS Core 库和 Scankit 依赖;其次,在 AndroidManifest.xml 文件中添加相机访问和互联网访问权限;然后,在应用程序的 onCreate 方法中调用 HmsClient 进行初始化;接着,可以选择自定义扫描界面或使用 Scankit 提供的默认扫描界面;最后,实现 ScanCallback 接口以处理扫描成功和失败的回调。 HMS Scankit 内部集成了开源的 Zxing(Zebra Crossing)库,这是一个功能强大的条码和二维码处理库,提供了解码、生成、解析等多种功能,既可以单独使用,也可以与其他扫描框架结合使用。在 HMS Scankit 中,Zxing 经过优化,以更好地适应华为设备,从而提升扫描性能。 通常,ScanKitDemoGuide 包含了集成 HMS Scankit 的示例代码,涵盖扫描界面的布局、扫描操作的启动和停止以及扫描结果的处理等内容。开发者可以参考这些代码,快速掌握在自己的应用中实现扫码功能的方法。例如,启动扫描的方法如下: 处理扫描结果的回调如下: HMS Scankit 支持所有安卓手机,但在华为设备上能够提供最佳性能和体验,因为它针对华为硬件进行了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值