[LA 3942] Remember the Word
阿新 • • 發佈:2018-06-30
include IT bool c++ lan 模式匹配 ati std 前綴
Link:
LA 3942 傳送門
Solution:
感覺自己字符串不太行啊,要加練一些藍書上的水題了……
$Trie$+$dp$
轉移方程:$dp[i]=sum\{ dp[i+len(x)+1]\} (x為從第i位開始的字符串的前綴)$
計算一個字符串前綴的多模式匹配在$Trie$樹上跑一遍就行啦!
Code:
#include <bits/stdc++.h> using namespace std; const int MAXN=4e5+10,MOD=20071027; bool vis[MAXN]; char s[MAXN],tmp[MAXN]; int T,n,ch[MAXN][30],dp[MAXN],l,len,cnt=0,rt=0; int main() { while(~scanf("%s",s+1)) { memset(ch,0,sizeof(ch));memset(dp,0,sizeof(dp)); memset(vis,false,sizeof(vis)); T++;len=strlen(s+1); scanf("%d",&n);cnt=0; for(int i=1;i<=n;i++) { scanf("%s",tmp+1);l=strlen(tmp+1); int cur=rt; for(int j=1;j<=l;j++) { if(!ch[cur][tmp[j]-‘a‘]) ch[cur][tmp[j]-‘a‘]=++cnt; cur=ch[cur][tmp[j]-‘a‘]; } vis[cur]=true; } dp[len+1]=1; for(int i=len;i>=1;i--) { int cur=rt; for(int j=i;j<=len;j++) { if(!ch[cur][s[j]-‘a‘]) break; cur=ch[cur][s[j]-‘a‘]; if(vis[cur]) (dp[i]+=dp[j+1])%=MOD; } } printf("Case %d: %d\n",T,dp[1]); } return 0; }
[LA 3942] Remember the Word