概率生成函数学习笔记

本文参考:bztMinamoto露迭月巨佬的博客

前置知识:对生成函数有一定了解,有概率期望的一定基础。

定义:一个生成函数F(x),第i位表示某某为i的概率。

例题:[CTSC2006]歌唱王国

题意:

给定一个长度为的序列。然后每次掷一个平骰子(有m种值)并将其上的数字加入到初始为空的序列的末尾,如果序列中已经出现了给定序列,即的子串,则停止。

题解:

时间停止的概率,时间不停止的概率,,分别为它们的生成函数。

这其实是

考虑对这个式子做出变形,两边同时求导

,

考虑求出

介绍一个东西:对于一个长度为的序列,若,则称的一个

定义=

带入

求出即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define next Next
#define gc getchar
#define int long long
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
inline int read()
{
    int ret=0,f=0;char c=gc();
    while(!isdigit(c)){if(c=='-')f=1;c=gc();}
    while(isdigit(c)){ret=ret*10+c-48;c=gc();}
    if(f)return -ret;return ret;
}
const int N=1e5+5,P=1e4;
inline int add(int x,int y){return x+y>=P?x+y-P:x+y;}
inline int mul(int x,int y){return 1ll*x*y%P;}
int n,p,res,pos,bin[N],nxt[N],a[N];
signed main()
{
    p=read(),bin[0]=1;
    for(int i=1;i<=100000;i++)bin[i]=mul(bin[i-1],p);
    int T=read();
    while(T--)
    {
        n=read();
        for(int i=1;i<=n;i++)a[i]=read();
        nxt[0]=nxt[1]=0;
        for(int i=2,j=0;i<=n;i++)
        {
            while(j&&a[j+1]!=a[i])j=nxt[j];
            j+=(a[j+1]==a[i]);
            nxt[i]=j;
        }
        pos=n,res=0;
        while(pos)
        {
            res=add(res,bin[pos]);
            pos=nxt[pos];
        }
        printf("%04lld\n",res);
    }
    return 0;
}

例题:[CTSC2006]歌唱王国

代码:

#include<bits/stdc++.h>
using namespace std;
#define next Next
#define gc getchar
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
inline int read()
{
    int ret=0,f=0;char c=gc();
    while(!isdigit(c)){if(c=='-')f=1;c=gc();}
    while(isdigit(c)){ret=ret*10+c-48;c=gc();}
    if(f)return -ret;return ret;
}
const int N=305;
const int P=1e9+7;
const double eps=1e-10;
double a[N][N],b[N];
char s[N];
int n,m,bin[N],h[N][N];
inline int Hash(int i,int l,int r){return ((h[i][r]-1ll*h[i][l-1]*bin[r-l+1])%P+P)%P;}
void Gauss(int n)
{
    for(int i=1;i<=n;i++)
    {
        if(a[i][i]>-eps&&a[i][i]<eps)
        {
            for(int j=i+1;j<=n;j++)if(a[j][i]<-eps||a[j][i]>eps)
            {
                for(int k=i;k<=n+1;k++)swap(a[i][k],a[j][k]);
                break;
            }
        }
        double t=1.0/a[i][i];
        for(int j=i;j<=n+1;j++)a[i][j]*=t;
        for(int j=i+1;j<=n;j++)
        {
            t=a[j][i];
            for(int k=i;k<=n+1;k++)a[j][k]-=a[i][k]*t;
        }
    }
    for(int i=n-1;i;i--)
        for(int j=i+1;j<=n;j++)a[i][n+1]-=a[j][n+1]*a[i][j];
}
int main()
{
    n=read();m=read();
    bin[0]=b[0]=1;
    for(int i=1;i<=m;i++)bin[i]=1ll*bin[i-1]*2%P,b[i]=b[i-1]*2;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        for(int j=1;j<=m;j++)h[i][j]=(1ll*h[i][j-1]*2+(s[j]=='H'))%P;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
            for(int k=1;k<=m;k++)(Hash(i,1,k)==Hash(j,m-k+1,m))?a[i][j]+=b[k]:0;
        a[i][n+1]=-1;
    }
    for(int i=1;i<=n;i++)a[n+1][i]=1;
    a[n+1][n+2]=1;
    Gauss(n+1);
    for(int i=1;i<=n;i++)printf("%.8lf\n",a[i][n+2]);
    return 0;
}
xuxuxuxuxu 文章被收录于专栏

信息学竞赛

全部评论
%%%
点赞 回复 分享
发布于 2019-08-10 19:57
太睿智了
点赞 回复 分享
发布于 2019-08-05 20:22

相关推荐

fRank1e:吓得我不敢去外包了,但是目前也只有外包这一个实习,我还要继续去吗
点赞 评论 收藏
分享
就前几天旅游的时候,打开抖音就经常刷到这类视频:以前是高学历学生、老师、主持人,现在做着团播、擦边主播的工作,以及那些经过精心包装的“职业转型”故事——从铺天盖地的VLOG到所谓的“04年夜场工作日记”,这些内容在初中升学、高考放榜等关键时间节点持续发酵。可以说非常直接且精准地在潜移默化地影响着心智尚未成熟的青少年,使其对特殊行业逐渐脱敏。那我就想问了:某些传播公司、平台运营者甚至某些夜场的老板,你们究竟在传递怎样的价值观?点开那些视频,评论区里也是呈现明显的两极分化:一种是​​经济下行论​​:“现在就业市场已经艰难到这种程度了吗?”​​一种是事实反驳派​​:这些创作者往往拥有名校背景,从事着...
牛客刘北:被环境教育的,为了能拿到足够的钱养活自己,不甘心也得甘心,现在的短视频传播的思想的确很扭曲,但是很明显,互联网玩上一年你就能全款提A6,但你全心全意不吃不喝工作一年未必能提A6,但是在高考中考出现这个的确很扭曲,在向大家传播“不上学,玩互联网也可以轻松年入百万”,不是人变了,是社会在变
预测一下26届秋招形势
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务