考虑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. KMP入门

    First.先上一份最原始的无任何优化的代码(暴力): #include <iostream> #include <cstring> using namespace std; ...

  2. Aaronson,又是思维题

    题目: Recently, Peter saw the equation x0+2x1+4x2+...+2mxm=nx0+2x1+4x2+...+2mxm=n. He wants to find a ...

  3. Error: error getting chaincode bytes: failed to calculate dependencies报错解决办法

    Error: error getting chaincode bytes: failed to calculate dependencies: incomplete package: github.c ...

  4. 006.Nginx访问控制

    一 Nginx连接限制 1.1 HTTP协议的连接与请求 HTTP是建立在TCP, 一次HTTP请求需要先建立TCP三次握手(称为TCP连接),在连接的基础上再进行HTTP请求. HTTP请求建立在一 ...

  5. CVE-2020-0796 漏洞复现

    漏洞介绍 2020年3月10日,微软在其官方SRC发布了CVE-2020-0796的安全公告(ADV200005,MicrosoftGuidance for Disabling SMBv3 Compr ...

  6. python numpy indexerror: too many indices for array

    import numpy as np #data 原来数组 #arr_1 新数组 #将data的第一列赋值给arr_1的第一列 arr_1 = np.array((data.shape[0],5)) ...

  7. 数据可视化之powerBI基础(二)PowerBI动态图表技巧:钻取交互

    https://zhuanlan.zhihu.com/p/64406366 查看可视化图表的时候,我们可能想深入了解某个视觉对象的更详细信息,或者进行更细粒度的分析,比如看到2017年的总体数据,同时 ...

  8. 神经网络结构:DenseNet

    论文地址:密集连接的卷积神经网络 博客地址(转载请引用):https://www.cnblogs.com/LXP-Never/p/13289045.html 前言 在计算机视觉还是音频领域,卷积神经网 ...

  9. 从JDK源码理解java引用

    目录 java中的引用 引用队列 虚引用.弱引用.软引用的实现 ReferenceHandler线程 引用队列的实现 总结 参考资料 java中的引用 JDK 1.2之后,把对象的引用分为了四种类型, ...

  10. OSCP Learning Notes - Buffer Overflows(4)

    Finding the Right Module(mona) Mona Module Project website: https://github.com/corelan/mona 1. Downl ...