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


考虑40分。
设出状态 f[i]表示匹配到了i位还有多少期望长度能停止。可以发现这个状态有环 需要高斯消元。
提供一种比较简单的方法:由于期望的线性可加性 可以设状态f[i]表示由匹配到i到匹配到i+1需要的期望长度。
需要预处理前缀和和KMP的nex数组来辅助转移。
if(n==1)
{
gc(a);
len=strlen(a+1);
ll j=0;
memset(nex,0,sizeof(nex));
rep(2,len,i)
{
while(j&&a[i]!=a[j+1])j=nex[j];
if(a[i]==a[j+1])++j;
nex[i]=j;
}
rep(0,len-1,i)
{
f[i]=1;
for(ll j=0;j<=25;++j)
{
if(a[i+1]-'a'!=j)
{
ll w=i;
while(w&&a[w+1]-'a'!=j)w=nex[w];
if(a[w+1]-'a'!=j){if(i)f[i]=(f[i]+sum[i-1])%mod;}
else f[i]=(f[i]+sum[i-1]-sum[w])%mod;
++f[i];
}
}
if(i>=1)sum[i]=(sum[i-1]+f[i])%mod;
else sum[i]=f[i];
}
ll ans=0;
rep(0,len-1,i)ans=(ans+f[i])%mod;
putl(ans);
}
考虑正解。
容易想到建立出AC自动机 在trie图上跑。
易设状态f[i]表示到达i这个点的期望长度。
遗憾的是 这个玩意根本不能转移。或者说转移必然存在问题 比如 \(f_i=\sum_{v\in fa[i],vis[v]\neq 1}\frac{f_v+1}{26}\)
vis数组表示v是否是终止节点。
容易想错的是 v转移到i的概率确实是1/26 但是i从v处转移的概率却不一定是1/26.
可能到达v的次数有很多次 每次概率都是1/26不过这个次数并没有被统计到 这是关键点。
而且据EI dalao所说 v转移到i的所有的概率和不为1 而且 E[x/y] 通常不等于 E[x]/E[y]。
总之 当做概率出现的问题吧.
考虑由最开始的状态倒推期望 设f[i]表示到达i这个节点还需要多少长度才能停止。
容易 发现转移 \(f_i=1+\sum_{v\in son[i]}\frac{f_v}{26}\)
可以发现这个状态的转移概率确实1/26.
而且这个状态带环。所以高斯消元即可。
const ll MAXN=12,maxn=210;
ll T,n,len,cnt;
inline ll ksm(ll b,ll p){ll cnt=1;while(p){if(p&1)cnt=(ll)cnt*b%mod;b=(ll)b*b%mod;p=p>>1;}return cnt;}
char a[maxn];
ll nex[maxn],q[maxn];
ll b[maxn][maxn];
ll f[maxn],sum[maxn];//f[i]表示由长度i到长度i+1的期望.
struct AC
{
ll s;
ll fail;
ll ch[26];
}t[maxn];
inline ll get_new()
{
++cnt;
t[cnt]=t[200];
return cnt;
}
inline void insert(char *a)
{
ll p=0;
ll len=strlen(a+1);
rep(1,len,i)
{
ll w=a[i]-'a';
if(!t[p].ch[w])t[p].ch[w]=get_new();
p=t[p].ch[w];
}
t[p].s=1;
}
inline void get_fail()
{
ll l=0,r=0;
rep(0,25,i)if(t[0].ch[i])q[++r]=t[0].ch[i];
while(++l<=r)
{
ll x=q[l];
rep(0,25,i)
{
ll tn=t[x].ch[i];
if(tn)fail(tn)=t[fail(x)].ch[i],q[++r]=tn;
else t[x].ch[i]=t[fail(x)].ch[i];
}
}
rep(1,r,i)t[q[i]].s|=t[fail(q[i])].s;
}
inline void GAUSS()
{
rep(0,cnt,i)
{
ll p=i;
rep(i+1,cnt,j)if(abs(b[j][i])>abs(b[i][i]))p=j;
if(p!=i){rep(0,cnt,k)swap(b[i][k],b[p][k]);swap(f[i],f[p]);}
ll d=ksm(b[i][i],mod-2);
rep(0,cnt,j)
{
if(i==j)continue;
ll ww=d*b[j][i]%mod;
rep(0,cnt,k)b[j][k]=(b[j][k]-b[i][k]*ww)%mod;
f[j]=(f[j]-f[i]*ww)%mod;
}
}
rep(0,cnt,i)f[i]=f[i]*ksm(b[i][i],mod-2)%mod;
}
signed main()
{
freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
//freopen("substring.in","r",stdin);
//freopen("substring.out","w",stdout);
gt(T);
while(T--)
{
gt(n);
{
cnt=0;t[0]=t[200];
rep(1,n,i)gc(a),insert(a);
get_fail();
//构建矩阵.
ll ww=ksm(26,mod-2);
memset(f,0,sizeof(f));
memset(b,0,sizeof(b));
rep(0,cnt,i)
{
b[i][i]=1;
if(t[i].s)continue;
rep(0,25,j)
{
int tn=t[i].ch[j];
b[i][tn]=(b[i][tn]-ww)%mod;
}
++f[i];
}
/*rep(0,cnt,i)
{
rep(0,cnt,j)cout<<(b[i][j]+mod)%mod<<' ';
cout<<f[i]<<endl;
}*/
GAUSS();
/*rep(0,cnt,i)
{
rep(0,cnt,j)cout<<b[i][j]<<' ';
cout<<f[i]<<endl;
}*/
//ll ans=0;
//rep(1,cnt,i)if(t[i].s)ans=(ans+f[i])%mod;
//rep(0,cnt,i)putl((f[i]+mod)%mod);
putl((f[0]+mod)%mod);
}
}
return 0;
}
4.23 子串 AC自动机 概率期望 高斯消元的更多相关文章
- 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 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬 ...
- hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】
含高斯消元模板 2016沈阳区域赛http://acm.hdu.edu.cn/showproblem.php?pid=5955 Guessing the Dice Roll Time Limit: 2 ...
- [HNOI2011]XOR和路径 概率期望 高斯消元
题面 题解:因为异或不太好处理,,,因此按位来算,这样最后的答案就是每一位上的值乘对应的权值再求和.本着期望要倒退的原则,,,我们设$f[i]$表示从$i$到$n$,xor和为1的概率.那么观察$xo ...
- BZOJ4820 SDOI2017硬币游戏(概率期望+高斯消元+kmp)
容易想到的做法是建出AC自动机,高斯消元.然而自动机上节点数量是nm的. 注意到我们要求的变量只有n个,考虑将其他不用求的节点合并为一个变量.这个变量即表示随机生成一个串,其不包含任何一个模板串的概率 ...
- bzoj 1444 AC自动机 + 矩阵乘法 | 高斯消元
恶补了一下AC自动机,花了一天时间终于全部搞明白了. 思路:将每个人的串加入AC自动机,在AC自动机生成的状态图上建边,注意单词末尾的节点只能转移到自己概率为1, 然后将矩阵自乘几十次后误差就很小了, ...
- BZOJ.3143.[HNOI2013]游走(概率 期望 高斯消元)
题目链接 参考 远航之曲 把走每条边的概率乘上分配的标号就是它的期望,所以我们肯定是把大的编号分配给走的概率最低的边. 我们只要计算出经过所有点的概率,就可以得出经过一条边(\(u->v\))的 ...
- luoguP4457 [BJOI2018]治疗之雨 概率期望 + 高斯消元
应该是最后一道紫色的概率了....然而颜色啥也代表不了.... 首先看懂题意: 你现在有$p$点体力,你的体力上限为$n$ 在一轮中, 1.如果你的体力没有满,你有$\frac{1}{m + 1}$的 ...
- [HNOI2013] 游走 - 概率期望,高斯消元,贪心
假如我们知道了每条边经过的期望次数,则变成了一个显然的贪心.现在考虑如何求期望次数. 由于走到每个点后各向等概率,很显然一条边的期望次数可以与它的两个端点的期望次数,转化为求点的期望次数 考虑每个点对 ...
随机推荐
- html table表格斜线表头的实现方法总汇
在html中给table加一个斜线的表头有时是很有必要的,但是到底该怎么实现这种效果呢?总结了以下几种方法: 1.UI背景图实现 直接去找公司的UI,让她做一张图片,作为背景图片放到这里,然后撑满就可 ...
- 3.第一个scrapy项目
第一个scrapy项目 1. 创建scrapy项目 1.1 创建项目三剑客 这里的三剑客指的是:创建项目以及运行项目的三条命令 1.1.1 创建项目 scrapy stratproject 项目名称 ...
- 在Linux上部署jmeter
一.服务器安装jmeter 1.将安装文件上传到Linux服务器 通过xshell文件上传工具,将文件 “apache-jmeter-5.1.1.tgz”上传 2.在服务器解压缩“apache-jme ...
- CSRF原理及防御
CSRF原理及防御 CSRF攻击原理 CSRF攻击利用网站对用户的信任,以用户的身份发送请求来执行攻击者所要的操作,比如:转账.发邮件.修改密码.添加用户等. CSRF和XSS一样危害都特别大,只不过 ...
- selenium 下拉到页面最底端
selenium操控浏览器下拉到页面最底端: https://www.cnblogs.com/TTyb/p/7662430.html #!/usr/bin/env python # -*- codin ...
- 轮播图-bxslider
bxSlider下载+参数说明 “bxSlider”就是一款响应式的幻灯片js插件 bxSlider特性 充分响应各种设备,适应各种屏幕: 支持多种滑动模式,水平.垂直以及淡入淡出效果: 支持图片.视 ...
- 找出系统web路径
方法一 :打开web查看源码,复制一个特征字符串,然后替换进下面命令的htmlString搜索之. Win :findstr /s/i/n /d:E:\code\xampp\htdocs\ /c:&q ...
- P4554 小明的游戏 (洛谷) 双端队列BFS
最近没有更新博客,全是因为英语,英语太难了QWQ 洛谷春令营的作业我也不会(我是弱鸡),随机跳了2个题,难度不高,还是讲讲吧,学学新算法也好(可以拿来水博客) 第一题就是这个小明的游戏 小明最近喜欢玩 ...
- C#中的类与对象
类:说白了就是类型,是对具体事物的一种抽象总结. 对象:一个具体的事物. 类与对象的关系,类实例化就会得到一个对象,同样一个对象也应该属于某一个类.例如张三这个人,他是一个对象,同时他属于人类,在程序 ...
- STL源码剖析:配接器
启 配接器就是适配器 STL中的适配器一共三种: 迭代器适配器 是一种观念上的改变,如将赋值操作变成插入,前进变成后退,等 函数适配器 STL中最广泛的配接器群体 可以实现连续配接 配接操作:bind ...