日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)

發布時間:2025/3/14 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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\n",tp-ans+1); 83 } 84 return 0; 85 } View Code

?

轉載于:https://www.cnblogs.com/bin-gege/p/5711453.html

總結

以上是生活随笔為你收集整理的hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。