题目大意:给你一些模板串和组成这些模板串的字符,从中随机选L个字符,每个字符都有各自被选的概率p,保证p之和为1,问抽到的串不包含模板串的概率
建一颗tire树,不能走打了tag的标记,走每条边概率已知,求走到深度L的概率,dp[i][j]表示到第i个点还能走j步的概率,转移即可
但这样做存在问题,可能某个短串是长串的子串,但是上述做法无法判断
可以建一颗tire树,从某个节点不断走fail,要求fail路径上的点都没有tag标记
其实这就是last的功能,即最近一个t串相同的ag标记的位置
莫名其妙空间开大了过不了,开小了过了,没有memset p数组过不了,memset了过了,是不是数据出的有问题,串中含有给的字符里没有的字符?
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <cmath> 9 #define min(a, b) ((a) < (b) ? (a) : (b)) 10 #define max(a, b) ((a) > (b) ? (a) : (b)) 11 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a)) 12 inline void swap(int &a, int &b) 13 { 14 long long tmp = a;a = b;b = tmp; 15 } 16 inline void read(int &x) 17 { 18 x = 0;char ch = getchar(), c = ch; 19 while(ch < '0' || ch > '9') c = ch, ch = getchar(); 20 while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar(); 21 if(c == '-') x = -x; 22 } 23 24 const int INF = 0x3f3f3f3f; 25 26 int t, k, n, l, ch[2000][80], fail[2000], last[2000], cnt, tag[2000], ca, vis[2000][100]; 27 double p[800], dp[2000][100]; 28 char s[200][200], base[800]; 29 int check(char c) 30 { 31 if(c >= '0' && c <= '9') return c - '0' + 1; 32 if(c >= 'A' && c <= 'Z') return c - 'A' + 11; 33 return c - 'a' + 37; 34 } 35 void insert(int x) 36 { 37 int now = 0; 38 for(register int i = 1;s[x][i] != '