【bzoj1444】【jsoi2009】【有趣的游戏】【AC自动机+矩阵乘法】

2024-02-20 15:08

本文主要是介绍【bzoj1444】【jsoi2009】【有趣的游戏】【AC自动机+矩阵乘法】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description

Input

注意 是0<=P

Output

Sample Input


Sample Output


HINT

 30%的数据保证, n ≤ 2. 50%的数据保证, n ≤ 5. 100%的数据保证, n , l, m≤ 10.

题解:

         对所有玩家的串建立AC自动机.

         对于非单词节点,我们按概率转移到其他点.

         对于单词节点我们向它自己连一条概率为1的边.

         这样既可以累加答案有保证了不会从单词节点向外转移.

         这样就算出了在AC自动机上的转移矩阵a.

         对于第i个串,它在AC自动机上结束的位置是pos[i]

         那第i个串的答案就是a[1][pos[i]]的值.

         将转移矩阵自乘上几十遍就可以保证精度.

代码:

       

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 200
using namespace std;
int a[N][30],cnt=1,x,y,n,l,m,q[N],fail[N],pos[N],id[N];
char ch[N];
double p[N];
int read(){int x(0);char ch=getchar();while (ch<'0'||ch>'9') ch=getchar();while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x;
}
struct use{double a[N][N];use(){memset(a,0,sizeof(a));}friend use operator*(use a,use b){use ans;for (int i=1;i<=cnt;i++)for (int j=1;j<=cnt;j++)for (int k=1;k<=cnt;k++)ans.a[i][j]+=a.a[i][k]*b.a[k][j];return ans;}
}c;
void insert(int x){int len=strlen(ch),now=1;for (int i=0;i<len;i++){int u=ch[i]-'A'+1;if (a[now][u]) now=a[now][u];else a[now][u]=++cnt,now=a[now][u];}pos[now]=1;id[x]=now;
}
void getfail(){int h(0),t(1);q[0]=1;fail[1]=0;while (h<t){int u=q[h++];for (int i=1;i<=m;i++){if (!a[u][i]) continue;int k=fail[u];while (!a[k][i]) k=fail[k];fail[a[u][i]]=a[k][i];if (pos[a[k][i]]) pos[a[u][i]]=1;q[t++]=a[u][i];}}
}
void getmatrix(){//cout<<a[1][2]<<endl;for (int i=1;i<=cnt;i++) if (pos[i]) c.a[i][i]=1;else{for (int j=1;j<=m;j++){int u=i;while (!a[u][j]) u=fail[u];u=a[u][j];c.a[i][u]+=p[j]; }}
}
int main(){//freopen("a.in","r",stdin);n=read();l=read();m=read();for (int i=1;i<=m;i++){x=read();y=read();p[i]=(double)x/(double)y; }for (int i=1;i<=26;i++) a[0][i]=1; for (int i=1;i<=n;i++){scanf("%s",ch);insert(i);  }getfail();getmatrix();/*for (int i=1;i<=cnt;i++){for (int j=1;j<=cnt;j++)cout<<c.a[i][j]<<' ';cout<<endl;}*/for (int i=1;i<=50;i++) c=c*c;for (int i=1;i<=n;i++) printf("%.2lf\n",c.a[1][id[i]]);
}

这篇关于【bzoj1444】【jsoi2009】【有趣的游戏】【AC自动机+矩阵乘法】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/728613

相关文章

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

POJ 1625 自动机

给出包含n个可见字符的字符集,以下所提字符串均由该字符集中的字符构成。给出p个长度不超过10的字符串,求长为m且不包含上述p个字符串的字符串有多少个。 g++提交 int mat[108][108] ;int matn ;int N ;map<char ,int> to ;//ACconst int maxm = 108 ;const int kin

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @