zoukankan      html  css  js  c++  java
  • hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)

    题目链接:hdu_2243_考研路茫茫——单词情结

    题意:

    让你求包含这些模式串并且长度不小于L的单词种类

    题解:

    这题是poj2788的升级版,没做过的强烈建议先做那题。

    我们用poj2778的方法可以求出不包含这些单词的,然后算出全部种类数,相减就是答案

    全部种类数的公式为f[n]=1 + 26^1 + 26^2 +...26^n

    AC自动机建出来的矩阵需要在最后添加一列1,这样在矩阵快速幂的时候就能计算出从1~n的幂和

     1 #include<bits/stdc++.h>
     2 #define mst(a,b) memset(a,b,sizeof(a))
     3 #define F(i,a,b) for(int i=a;i<=b;i++)
     4 typedef unsigned long long ll;
     5 //-----------------------矩阵-------------------------
     6 const int mat_N=6*7+7;//矩阵阶数
     7 int N;
     8 struct mat{
     9     ll c[mat_N][mat_N];
    10     void init(){mst(c,0);}
    11     mat operator*(mat b){
    12         mat M;M.init();
    13         F(i,0,N)F(j,0,N)F(k,0,N)M.c[i][j]=M.c[i][j]+c[i][k]*b.c[k][j];
    14         return M;
    15     }
    16     mat operator^(ll k){
    17         mat ans,M=(*this);ans.init();
    18         F(i,0,N)ans.c[i][i]=1;
    19         while(k){if(k&1)ans=ans*M;k>>=1,M=M*M;}
    20         return ans;
    21     }
    22 }A;
    23 //-----------------------AC自动机-----------------------
    24 const int AC_N=6*8*26,tyn=26;//数量乘串长,类型数
    25 struct AC_automation{
    26     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
    27     inline int getid(char x){return x-'a';}
    28     void nw(){cnt[++tot]=0;memset(tr[tot],-1,sizeof(tr[tot]));}
    29     void init(){tot=-1,fail[0]=-1,nw();}
    30     void insert(char *s,int x=0){
    31         for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++)
    32             if(tr[x][w=getid(s[i])]==-1)nw(),tr[x][w]=tot;
    33         cnt[x]++;//串尾标记
    34     }
    35     void build(int head=1,int tail=0){
    36         for(Q[++tail]=0;head<=tail;){
    37             for(int i=0,x=Q[head++],p=-1;i<tyn;i++)if(~tr[x][i]){
    38                 if(x==0)fail[tr[0][i]]=0;
    39                 else for(p=fail[x],fail[tr[x][i]]=0;~p;p=fail[p])
    40                         if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;}
    41                 if(cnt[fail[tr[x][i]]])cnt[tr[x][i]]=1;
    42                 Q[++tail]=tr[x][i];
    43             }else if(x==0)tr[x][i]=0;
    44             else tr[x][i]=tr[fail[x]][i];
    45         }
    46     }
    47 }AC;
    48 
    49 void build_mat()
    50 {
    51     A.init();
    52     F(i,0,AC.tot)F(j,0,25)if(!AC.cnt[i]&&!AC.cnt[AC.tr[i][j]])A.c[i][AC.tr[i][j]]++;
    53     N=AC.tot+1;
    54     F(i,0,N)A.c[i][N]=1;//矩阵添加一列1,能将矩阵从1~n的幂和算出来
    55 }
    56 
    57 ll q_pow(ll k)
    58 {
    59     unsigned long long ans=1,tp=26;
    60     while(k){if(k&1)ans*=tp;k>>=1,tp*=tp;}
    61     return ans;
    62 }
    63 
    64 ll f_ck(ll k)//计算26的从1~k的幂和
    65 {
    66     if(k==1)return 26;
    67     ll t=0;
    68     if(k&1)t=q_pow(k);
    69     return (1+q_pow(k>>1))*f_ck(k>>1)+t;
    70 }
    71 
    72 int main()
    73 {
    74     ll n,m,ans,tp;char buf[30];
    75     while(~scanf("%llu%llu",&n,&m))
    76     {
    77         AC.init();
    78         F(i,1,n)scanf("%s",buf),AC.insert(buf);
    79         AC.build(),build_mat(),A=A^m,ans=0;
    80         F(i,0,N)ans+=A.c[0][i];
    81         tp=f_ck(m);
    82         printf("%llu
    ",tp-ans+1);
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    Druid 使用 Kafka 将数据载入到 Kafka
    Druid 使用 Kafka 数据加载教程——下载和启动 Kafka
    Druid 集群方式部署 —— 启动服务
    Druid 集群方式部署 —— 端口调整
    Druid 集群方式部署 —— 配置调整
    Druid 集群方式部署 —— 配置 Zookeeper 连接
    Druid 集群方式部署 —— 元数据和深度存储
    Druid 集群方式部署 —— 从独立服务器部署上合并到集群的硬件配置
    Druid 集群方式部署 —— 选择硬件
    Druid 独立服务器方式部署文档
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5711453.html
Copyright © 2011-2022 走看看