總結
這個關鍵點在於,每個單詞的最大長度是1e2,然後我們可以倒序枚舉後綴,dp枚舉向右遞推最多100,O(L*100+Slog100)
題目鏈接
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
//typedef long long ll;
#define ull unsigned long long
#define int long long
#define F first
#define S second
#define endl "\n"//<<flush
#define eps 1e-6
#define base 131
#define lowbit(x) (x&(-x))
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define MAXN 0x7fffffff
#define INF 0x3f3f3f3f3f3f3f3f
#define ferma(a,b) pow(a,b-2)
#define pb push_back
#define all(x) x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
void file()
{
#ifdef ONLINE_JUDGE
#else
freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
// freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}
const int N=3e5+5;
const int M=4e6+5;
const int mod=20071027;
int son[M][26],pos=0,cnt[M],dp[N];
void insert(string &t)
{
int p=0;
for(auto it:t)
{
int &value=son[p][it-'a'];
if(!value)
value=++pos;
p=value;
}
cnt[p]++;
}
void query(int ac,string &s,int len)
{
int p=0;
for(int i=ac;i<len;i++)
{
int value=son[p][s[i]-'a'];
if(!value)
break;
if(cnt[value])
dp[ac]=(dp[ac]+cnt[value]*dp[i+1]%mod)%mod;
p=value;
}
}
signed main()
{
IOS;
// file();
string s,t;
int num=0;
while(cin>>s)
{
int n;
cin>>n;
while(n--)
{
cin>>t;
insert(t);
}
int len=s.size();
dp[len]=1;
for(int i=len-1;i>=0;i--)
{
query(i,s,len);
}
cout<<"Case "<<++num<<": ";
cout<<dp[0]<<endl;
for(int i=0;i<=len;i++)
dp[i]=0;
for(int i=0;i<=pos;i++)
{
memset(son[i],0);
cnt[i]=0;
}
pos=0;
}
return 0;
}