考虑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自动机 概率期望 高斯消元的更多相关文章

  1. 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 ...

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

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

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

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

  4. [HNOI2011]XOR和路径 概率期望 高斯消元

    题面 题解:因为异或不太好处理,,,因此按位来算,这样最后的答案就是每一位上的值乘对应的权值再求和.本着期望要倒退的原则,,,我们设$f[i]$表示从$i$到$n$,xor和为1的概率.那么观察$xo ...

  5. BZOJ4820 SDOI2017硬币游戏(概率期望+高斯消元+kmp)

    容易想到的做法是建出AC自动机,高斯消元.然而自动机上节点数量是nm的. 注意到我们要求的变量只有n个,考虑将其他不用求的节点合并为一个变量.这个变量即表示随机生成一个串,其不包含任何一个模板串的概率 ...

  6. bzoj 1444 AC自动机 + 矩阵乘法 | 高斯消元

    恶补了一下AC自动机,花了一天时间终于全部搞明白了. 思路:将每个人的串加入AC自动机,在AC自动机生成的状态图上建边,注意单词末尾的节点只能转移到自己概率为1, 然后将矩阵自乘几十次后误差就很小了, ...

  7. BZOJ.3143.[HNOI2013]游走(概率 期望 高斯消元)

    题目链接 参考 远航之曲 把走每条边的概率乘上分配的标号就是它的期望,所以我们肯定是把大的编号分配给走的概率最低的边. 我们只要计算出经过所有点的概率,就可以得出经过一条边(\(u->v\))的 ...

  8. luoguP4457 [BJOI2018]治疗之雨 概率期望 + 高斯消元

    应该是最后一道紫色的概率了....然而颜色啥也代表不了.... 首先看懂题意: 你现在有$p$点体力,你的体力上限为$n$ 在一轮中, 1.如果你的体力没有满,你有$\frac{1}{m + 1}$的 ...

  9. [HNOI2013] 游走 - 概率期望,高斯消元,贪心

    假如我们知道了每条边经过的期望次数,则变成了一个显然的贪心.现在考虑如何求期望次数. 由于走到每个点后各向等概率,很显然一条边的期望次数可以与它的两个端点的期望次数,转化为求点的期望次数 考虑每个点对 ...

随机推荐

  1. css中vertical-aling与line-height

    基线 baseline:字符x的底部 x-height: 字母x的高度,vertical-aling设置为middle的时候,对齐的是baseline往上1/2的x-height,所以vertical ...

  2. C++中cin>>a原理

    int a; vector<int>res; while(cin>>a){ res.push_back(a); } 给出这段代码 可以输入1 2  3 4 5并以回车结束,从而 ...

  3. Django---进阶8

    目录 前后端传输数据的编码格式(contentType) ajax发送json格式数据 ajax发送文件 django自带的序列化组件(drf做铺垫) ajax结合sweetalert 批量插入 分页 ...

  4. Alink漫谈(十) :线性回归实现 之 数据预处理

    Alink漫谈(十) :线性回归实现 之 数据预处理 目录 Alink漫谈(十) :线性回归实现 之 数据预处理 0x00 摘要 0x01 概念 1.1 线性回归 1.2 优化模型 1.3 损失函数& ...

  5. java 面向对象(二十二):关键字:final

    final:最终的1.可以用来修饰:类.方法.变量 2.具体的: 2.1 final 用来修饰一个类:此类不能被其他类所继承. * 比如:String类.System类.StringBuffer类 * ...

  6. 数据可视化之powerBI技巧(二十四)Power BI初学者刚见的错误,帮你轻松处理

    在学习PowerBI的过程中,尤其是刚接触的时候,不可避免的会遇到各种各样的错误,有时自己怎么检查都没法消除,不解决这个错误又没法进行下一步的工作,经常会搞的自己烦闷无比,不过最后通过自己的苦苦摸索. ...

  7. Flask 基础组件(五):请求和响应

    from flask import Flask from flask import request from flask import render_template from flask impor ...

  8. P2070 刷墙 (洛谷)

    题目描述 Farmer John已经设计了一种方法来装饰谷仓旁边的长栅栏(把栅栏认为是一根一维的线).他把一只画刷绑在他最喜爱的奶牛Bessie身上,之后就去喝一杯冰水,而Bessie隔着栅栏来回走, ...

  9. 关于Java8的精心总结

    前言 ​ 最近公司里比较新的项目里面,看到了很多关于java8新特性的用法,由于之前自己对java8的新特性不是很了解也没有去做深入研究,所以最近就系统的去学习了一下,然后总结了一篇文章第一时间和大家 ...

  10. SQL 给某字段添加汉字却显示??

    错误展示: 解决方案: 1.在要修改的数据库上单击鼠标右键,并选择“属性”.   2.在弹出的数据库属性窗口中点击“选择页”中的“选项”.   3.将排序规则由默认的SQL_Latin1_Genera ...