Substring
Given
a set of pattern strings, and a text, you have to find, if any of the pattern is a substring of the text. If any of the pattern string can be found in text, then print “yes”, otherwise “no” (without quotes).
But,
unfortunately, that’s not what is asked here. J
The
problem described above, requires a input file generator. The generator generates a text of length L, by choosing L characters randomly. Probability of choosing each character is given as priori, and independent of choosing others.
Now,
given a set of patterns, calculate the probability of a valid program generating “no”.
Input
First
line contains an integer T, the number of test cases. Each case starts with an integer K, the number of pattern strings. Next K lines each contain a pattern string, followed by an integer N, number of valid characters. Next N lines
each contain a character and the probability of selecting that character, pi. Next an integer L, the length of the string generated. The generated text can consist of only the valid characters, given above.
There
will be a blank line after each test case.
Output
For
each test case, output the number of test case, and the probability of getting a “no”.
Constraints
· T ≤
50
· K
≤ 20
· Length
of each pattern string is between 1 and 20
· Each
pattern string consists of only alphanumeric characters (‘a’ to ‘z’, ‘A’ to ‘Z’,’0’ to ‘9’)
· Valid
characters are all alphanumeric characters
· ∑pi =
1
· L
≤ 100
Sample
input
2
1
a
2
a
0.5
b
0.5
2
2
ab
ab
2
a
0.2
b
0.8
2
Output
for Sample Input
Case
#1: 0.250000
Case
#2: 0.840000
本题利用了AC自动机
首先,把模式串p推入AC自动机,然后dp[i][j]表示匹配到i点没成功,还剩j个字符未匹配的概率,dp
注意AC自动机上的dp(我之前忘了getFail()了,,,考挂自己弱)
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> #include<queue> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define MAXT (50+10) #define MAXL (100+10) #define MAXN (20+10) #define MAXLen (20+10) #define MAXNode (400+10) #define Sigma_size (62) typedef long long ll; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int n,L; char s[MAXLen]; double prob[Sigma_size],dp[MAXNode][MAXL]; bool b[MAXNode][MAXL]; class Aho_Corasick_Automata { public: int ch[MAXNode][Sigma_size]; int v[MAXNode],siz; // AC自动机 int f[MAXNode],last[MAXNode]; Aho_Corasick_Automata(int _siz=0):siz(_siz){MEM(ch) MEM(v) MEM(f) MEM(last)} void mem(int _siz=0){siz=_siz; MEM(ch) MEM(v) MEM(f) MEM(last) } int idx(char c){return 'a'<=c&&c<='z'?c-'a':'A'<=c&&c<='Z'?c-'A'+26:c-'0'+52;} void insert(char *s,int val=0) { int u=0,n=strlen(s); Rep(i,n) { int c=idx(s[i]); if (!ch[u][c]) { ++siz; MEM(ch[siz]); ch[u][c]=siz; } u=ch[u][c]; } v[u]=val; } void getFail() { queue<int> q; Rep(c,Sigma_size) { int u=ch[0][c]; if (u) q.push(u),last[u]=0; } while (!q.empty()) { int r=q.front();q.pop(); //r--c-->u Rep(c,Sigma_size) { int u=ch[r][c]; if (!u) {ch[r][c]=ch[f[r]][c]; continue;} q.push(u); f[u]=ch[f[r]][c]; last[u]=v[f[u]]?f[u]:last[f[u]]; } } } void print(int j) //打印全串中所有以j为末尾的str { if (j) { printf("%d %d\n",j,v[j]); print(last[j]); } } void find(char *s) { int u=0,n=strlen(s); Rep(i,n) { int c=idx(s[i]); u=ch[u][c]; if (v[u]) print(u); else if (last[u]) print(u); } } double dfs(int u,int l) { if (!l) return 1; if (b[u][l]) return dp[u][l]; double ans=0.0; Rep(c,Sigma_size) if (prob[c]) { if (v[ch[u][c]]||last[ch[u][c]]) continue; ans+=prob[c]*dfs(ch[u][c],l-1); } b[u][l]=1; return dp[u][l]=ans; } }T; int main() { // freopen("uva11468.in","r",stdin); // freopen(".out","w",stdout); int kcase; scanf("%d",&kcase); For(tt,kcase) { T.mem(); MEM(dp) MEM(prob) MEM(b) scanf("%d",&n); For(i,n) { scanf("%s",s); T.insert(s,1); } T.getFail(); scanf("%d\n",&n); For(i,n) { char c; scanf("%c",&c); scanf("%lf\n",&prob[T.idx(c)]); } scanf("%d",&L); printf("Case #%d: %.6lf\n",tt,T.dfs(0,L)); } return 0; }