恶补了一下AC自动机,花了一天时间终于全部搞明白了。

思路:将每个人的串加入AC自动机,在AC自动机生成的状态图上建边,注意单词末尾的节点只能转移到自己概率为1,

然后将矩阵自乘几十次后误差就很小了, 或者可以高斯消元搞出精确解。

#include<bits/stdc++.h>
#define LL long long
#define ll long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg using namespace std; const int N = + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ; int n, l, m, pos[];
double pro[];
char s[]; struct Matrix {
int r, c;
double a[][];
Matrix(int r = , int c = ) {
this->r = r;
this->c = c;
memset(a, , sizeof(a));
} Matrix operator * (const Matrix &B) const {
Matrix C(r, c);
for(int i = ; i < r; i++)
for(int j = ; j < c; j++)
for(int k = ; k < r; k++)
C.a[i][j] += a[i][k] * B.a[k][j];
return C;
}
}; struct Ac {
int val[N], ch[N][], f[N], last[N], cnt, SZ; void init(int SZ = ) {
cnt = ; this->SZ = SZ;
for(int c = ; c < SZ; c++) ch[][c] = ;
} int getId(char c) {
return c - 'A';
} int newNode() {
cnt++;
memset(ch[cnt], , sizeof(ch[cnt]));
val[cnt] = f[cnt] = last[cnt] = ;
return cnt;
} void add(char *s, int &pos) {
int u = ;
for(int i = ; s[i]; i++) {
int c = getId(s[i]);
if(!ch[u][c]) ch[u][c] = newNode();
u = ch[u][c];
}
val[u]++;
pos = u;
} void build() {
queue<int> que;
f[] = ;
for(int c = ; c < SZ; c++) {
if(!ch[][c]) continue;
f[ch[][c]] = last[ch[][c]] = ;
que.push(ch[][c]);
}
while(!que.empty()) {
int u = que.front(); que.pop();
for(int c = ; c < SZ; c++) {
int v = ch[u][c];
if(!v) {
ch[u][c] = ch[f[u]][c];
continue;
} else {
que.push(v);
f[v] = ch[f[u]][c];
last[v] = val[f[v]] ? f[v] : last[f[v]];
}
}
}
} void buildMatrix(Matrix &A) {
for(int u = ; u <= cnt; u++) {
if(val[u]) A.a[u][u] = ;
else {
for(int c = ; c < m; c++) {
int v = ch[u][c];
A.a[u][v] += pro[c];
}
}
}
}
} ac; int main() {
scanf("%d%d%d", &n, &l, &m);
for(int i = ; i < m; i++) {
double p, q;
scanf("%lf%lf", &p, &q);
pro[i] = p / q;
} ac.init(m); for(int i = ; i <= n; i++) {
scanf("%s", s);
ac.add(s, pos[i]);
} ac.build();
Matrix A(ac.cnt + , ac.cnt + );
ac.buildMatrix(A); for(int i = ; i <= ; i++)
A = A * A; for(int i = ; i <= n; i++) printf("%.2f\n", A.a[][pos[i]]);
return ;
} /*
*/

bzoj 1444 AC自动机 + 矩阵乘法 | 高斯消元的更多相关文章

  1. hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】

    含高斯消元模板 2016沈阳区域赛http://acm.hdu.edu.cn/showproblem.php?pid=5955 Guessing the Dice Roll Time Limit: 2 ...

  2. 4.23 子串 AC自动机 概率期望 高斯消元

    考虑40分. 设出状态 f[i]表示匹配到了i位还有多少期望长度能停止.可以发现这个状态有环 需要高斯消元. 提供一种比较简单的方法:由于期望的线性可加性 可以设状态f[i]表示由匹配到i到匹配到i+ ...

  3. 2016ACM/ICPC亚洲区沈阳站H - Guessing the Dice Roll HDU - 5955 ac自动机+概率dp+高斯消元

    http://acm.hdu.edu.cn/showproblem.php?pid=5955 题意:给你长度为l的n组数,每个数1-6,每次扔色子,问你每个串第一次被匹配的概率是多少 题解:先建成ac ...

  4. 【BZOJ4820】[Sdoi2017]硬币游戏 AC自动机+概率DP+高斯消元

    [BZOJ4820][Sdoi2017]硬币游戏 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬 ...

  5. bzoj 3503: [Cqoi2014]和谐矩阵【高斯消元】

    如果确定了第一行,那么可以推出来整个矩阵,矩阵合法的条件是n+1行全是0 所以推出来n+1行和1行的关系,然后用异或高斯消元来解即可 #include<iostream> #include ...

  6. 【AC自动机】【高斯消元】hdu5955 Guessing the Dice Roll

    http://blog.csdn.net/viphong/article/details/53098489 我有一点不是很懂,这样算出来转移到AC自动机根节点的概率是一个远大于1的数. 按我的理解,因 ...

  7. BZOJ.4820.[SDOI2017]硬币游戏(思路 高斯消元 哈希/AC自动机/KMP)

    BZOJ 洛谷 建出AC自动机,每个点向两个儿子连边,可以得到一张有向图.参照 [SDOI2012]走迷宫 可以得到一个\(Tarjan\)+高斯消元的\(O((nm)^3)\)的做法.(理论有\(6 ...

  8. 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法

    题目描述 输入 注意 是0<=P 输出 样例输入 样例输出 题解 AC自动机+矩阵乘法 先将所有字符串放到AC自动机中,求出Trie图. 然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向 ...

  9. BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元

    BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元 题意: 我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本身,及他上下左右的4个元素(如果 ...

随机推荐

  1. Android网络请求的时候报错 Connection refused 处理

    在用Android测试JSON数据解析的时候,报了这样一个异常: java.net.ConnectException: localhost/ - Connection refused 原来模拟器默认把 ...

  2. Django请求原理(二)

    1,Web服务器(中间件)收到一个http请求 2,Django在URLconf里查找对应的视图(View)函数来处理http请求 3,视图函数调用相应的数据模型来存取数据.调用相应的模板向用户展示页 ...

  3. Kubernetes - Getting Started With Kubeadm

    In this scenario you'll learn how to bootstrap a Kubernetes cluster using Kubeadm. Kubeadm solves th ...

  4. jquery动画切换引擎插件 Velocity.js 学习02

    案例实践: 第一页会以动画形式进入页面: 点击进入按钮时,第一页以动画消失,第二页以动画形式进入,同时四张图片也定义从小到大的动画形式: 第二页关闭按钮点击时,先是四张图片以缩小动画消失,然后第二页以 ...

  5. 数据结构:K-D树

    K-D树实际上是一棵高维二叉搜索树,与普通二叉搜索树不同的是,树中存储的是一些K维数据 普通的二叉搜索树是一维的,当推广到K维后,就是我们的K-D树了 在K-D树中跟二叉搜索树差不多,也是将一个K维的 ...

  6. Bzoj1312 / POJ3155 Neerc2006 Hard Life

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 459  Solved: 114 Description 在一家公司中,人事部经理与业务部经理不和.一次 ...

  7. 20155335俞昆《java程序设计》第三周总结

    20155335  2006-2007-2  <Java程序设计>第三周学习总结 ##  教材学习内容总结 首先,关键是区基本类型和类类型,,产生对象必须定义类,类是一个概念,并不存在,对 ...

  8. python初步学习-pycharm使用 (二)

    pycharm调试模式 假设我们的程序在运行过程中命中了一个错误,那我们如何定位错误发生的位置?这就需要进行调试. 在Pycharm中我们可以在其中直接对程序进行调试,唯一需要做的准备工作就是在程序必 ...

  9. bzoj 1927 网络流

    首先我们可以知道这道题中每个点只能经过一次,那么我们引入附加源汇source,sink,那么我们可以将每个点拆成两个点,分别表示对于图中这个节点我们的进和出,那么我们可以连接(source,i,1,0 ...

  10. 用例图(Use Case Diagram)

    用例图(Use Case Diagram) 执行者/参与者(Actor): 表示与您的应用程序或系统进行交互的用户.组织或外部系统.用一个小人表示. 用例(Use Case): 即系统具有的功能,在用 ...