bzoj 1444 AC自动机 + 矩阵乘法 | 高斯消元
恶补了一下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自动机 + 矩阵乘法 | 高斯消元的更多相关文章
- hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】
含高斯消元模板 2016沈阳区域赛http://acm.hdu.edu.cn/showproblem.php?pid=5955 Guessing the Dice Roll Time Limit: 2 ...
- 4.23 子串 AC自动机 概率期望 高斯消元
考虑40分. 设出状态 f[i]表示匹配到了i位还有多少期望长度能停止.可以发现这个状态有环 需要高斯消元. 提供一种比较简单的方法:由于期望的线性可加性 可以设状态f[i]表示由匹配到i到匹配到i+ ...
- 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 ...
- 【BZOJ4820】[Sdoi2017]硬币游戏 AC自动机+概率DP+高斯消元
[BZOJ4820][Sdoi2017]硬币游戏 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬 ...
- bzoj 3503: [Cqoi2014]和谐矩阵【高斯消元】
如果确定了第一行,那么可以推出来整个矩阵,矩阵合法的条件是n+1行全是0 所以推出来n+1行和1行的关系,然后用异或高斯消元来解即可 #include<iostream> #include ...
- 【AC自动机】【高斯消元】hdu5955 Guessing the Dice Roll
http://blog.csdn.net/viphong/article/details/53098489 我有一点不是很懂,这样算出来转移到AC自动机根节点的概率是一个远大于1的数. 按我的理解,因 ...
- BZOJ.4820.[SDOI2017]硬币游戏(思路 高斯消元 哈希/AC自动机/KMP)
BZOJ 洛谷 建出AC自动机,每个点向两个儿子连边,可以得到一张有向图.参照 [SDOI2012]走迷宫 可以得到一个\(Tarjan\)+高斯消元的\(O((nm)^3)\)的做法.(理论有\(6 ...
- 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法
题目描述 输入 注意 是0<=P 输出 样例输入 样例输出 题解 AC自动机+矩阵乘法 先将所有字符串放到AC自动机中,求出Trie图. 然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向 ...
- BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元
BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元 题意: 我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本身,及他上下左右的4个元素(如果 ...
随机推荐
- Intervals ZOJ - 3953 (区间贪心)
Chiaki has n intervals and the i-th of them is [li, ri]. She wants to delete some intervals so that ...
- Rectangle 暴力枚举大法
frog has a piece of paper divided into n rows and m columns. Today, she would like to draw a rectang ...
- zabbix问题汇总
1. ::110809.577 resuming IPMI checks on host [10.1.3.41]: connection restored :: seconds :: seconds ...
- Linux下实现文档在线浏览
使用php实现百度文库功能,网上搜索到的方案,实现doc转pdf,pdf转swf,然后显示出来. 这里简单的记录下,[doc转pdf,pdf转swf]两个功能的搭建流程. doc转pdf 使用到下列程 ...
- linux内核挂载文件系统的两种方式
1.nfs方式(挂载的为文件夹) bootargs=root=/dev/nfs nfsroot=192.168.1.105:/mnt/rootfs/rootfs ip=192.168.1.88:192 ...
- java线程的3种创建方式及优缺点
线程创建简介 1.在java中表示线程的是Thread类.无论是那种方式创建线程,本质上都是创建Thread类的对象. 2.Thread类继承Runnable接口,且也有以Runnable作为参数的构 ...
- UVA 1645 Count
https://vjudge.net/problem/UVA-1645 题意:有多少个n个节点的有根树,每个深度中所有节点的子节点数相同 dp[i] 节点数为i时的答案 除去根节点还有i-1个点,如果 ...
- web版canvas做飞机大战游戏 总结
唠唠:两天的时间跟着做了个飞机大战的游戏,感觉做游戏挺好的.说是用html5做,发现全都是js.说js里一切皆为对象,写的最多的还是函数,都是函数调用.对这两天的代码做个总结,希望路过的大神指点一下, ...
- 【BZOJ4517】【SDOI2016】排列计数 [数论]
排列计数 Time Limit: 60 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 求有多少种长度为 n 的序列 A, ...
- [Unity]模拟雨水的折射效果
用GrabPass做的小玩具. 并不是真的计算了折射,只是简单地扰动了uv,对于雨水来说效果已经足够好了. Shader代码: Shader "Unlit/Rain" { Prop ...