• dtoj#4248. 走


    题目描述:

    题目还是简单一点好。

    有一张图,每一个点有至少一条出边,每条边上有一个小写字母。有一只大象在图上走路,一开始 在 $1$ 号点,之后每一步会随机选择该点的一条出边并走过去。
    将大象走过的边上的小写字母顺次相连,就构成了一个字符串。大象有两个串 $a$ 和 $b$,如果大象走 出的串包含 $a$ 作为 子串或包含 $b$ 作为子序列,大象就会很生气,停止行走。

    大象想知道在停止行走前大象期望会走几步。输入保证这个值是一个有理数,你只要输出它 $mod 998244353$ 的值即可。

    思路:

    对于会有正推会有无穷无尽的局面的概率期望问题,大多列出等式消元求解。

    考虑 $f[x][j][k]$ 表示在点 $x$ 上,当前走过的字符匹配到 $a$ 串比配到 $j$ ,匹配 $b$ 串匹配到 $k$ 的走过的步数的期望。

    有一个发现是答案在 $ f[?][?][|b|] $ 时答案为 $0$ ,可以考虑根据这个列出一个方程式,高斯消元,但是效率是 $O((abn)^{3})$

    但是我们发现最后一位一定是递增的,所以考虑每次制作 $k,k+1$ 的方程式,并高斯消元,最后答案是 $f[1][0][0]$ 。

    转移式:
    $$
    f[x][j][k]=sum ((f[to[i]][ne[j][w[i]]][k/k+1]+1) imes frac{1}{out[x]})
    $$
    $ne[j][ch]​$ 是提前预处理出对于 $a​$ 串,如果匹配到第 $j​$ 位下一位是 $ch​$ ,那么下一次可以匹配到哪里。

    如果走过的边上的字符恰好满足为 $b[k+1]​$ 时, 对应最后一维为 $k+1​$ 的 $f​$ 数组,即增加一个常数。

    否则则对左边对应项的系数造成改变。

     以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define LL long long
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=25,M=1e4+5,p=998244353;
    char s[55];
    int a[12],b[55],l1,l2,A[205][205],ne[N][28],f[N][12][55];
    int n,m,head[N],nex[M],to[M],cnt,w[M],out[N],id[N][12];
    il int read(){
        int x,f=1;char ch;
        _(!)ch=='-'?f=-1:f;x=ch^48;
        _()x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    il void insert(int x,int y,int z){
        nex[++cnt]=head[x];head[x]=cnt;
        to[cnt]=y;w[cnt]=z;out[x]++;
    }
    il int mu(int x,int y){
        return x+y>=p?x+y-p:x+y;
    }
    il int ksm(LL a,int y){
        LL b=1;
        while(y){
            if(y&1)b=b*a%p;
            a=a*a%p;y>>=1;
        }
        return b;
    }
    il bool pd(int x,int y){
        if(x==y)return 1;if(x==0)return 1;
        for(;x;x--,y--){
            if(a[x]!=a[y])return 0;
        }
        return 1;
    }
    il void Gauss(int n){
        for(int i=1,inv;i<=n;i++){
            if(!A[i][i]){
                int mx=i;
                for(int j=i+1;j<=n;j++)if(A[j][i]>A[mx][i])mx=j;
                if(i^mx)for(int j=0;j<=n;j++)swap(A[i][j],A[mx][j]);
            }
            if(!A[i][i])continue;inv=ksm(A[i][i],p-2);
            A[i][i]=1;A[i][0]=1ll*A[i][0]*inv%p;
            for(int j=i+1;j<=n;j++)A[i][j]=1ll*A[i][j]*inv%p;
            for(int j=1;j<=n;j++){
                if(i^j&&A[j][i]){
                    int g=A[j][i];A[j][0]=mu(A[j][0],p-1ll*g*A[i][0]%p);
                    for(int k=i;k<=n;k++)A[j][k]=mu(A[j][k],p-1ll*g*A[i][k]%p);
                    
                }
            }
        }
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=m;i++){
            int x=read(),y=read();scanf(" %s",s);
            insert(x,y,s[0]-'a');
        }
        scanf(" %s",s+1);l1=strlen(s+1);
        for(int i=1;i<=l1;i++)a[i]=s[i]-'a';
        scanf(" %s",s+1);l2=strlen(s+1);
        for(int i=1;i<=l2;i++)b[i]=s[i]-'a';
        for(int i=0;i<l1;i++)for(int j=0;j<26;j++)
            for(int k=i;k>=0;k--)if(a[k+1]==j&&pd(k,i)){
                ne[i][j]=k+1;break;
            }
        int tot=0;
        for(int i=1;i<=n;i++)for(int j=0;j<l1;j++)id[i][j]=++tot;
        for(int l=l2-1,x;l>=0;l--){
            for(int i=1;i<=n;i++)for(int j=0;j<l1;j++)
                x=id[i][j],A[x][0]=A[x][x]=out[i];
            for(int i=1;i<=n;i++)for(int j=0;j<l1;j++){
                x=id[i][j];
                for(int k=head[i];k;k=nex[k]){
                    int v=to[k],lj=ne[j][w[k]],lk=l+(w[k]==b[l+1]);
                    if(w[k]==b[l+1]||lj==l1)
                        A[x][0]=mu(A[x][0],f[v][lj][lk]);
                    else A[x][id[v][lj]]=mu(A[x][id[v][lj]],p-1);
                }
            }
            Gauss(tot);
            for(int i=1;i<=n;i++)for(int j=0;j<l1;j++)f[i][j][l]=A[id[i][j]][0];
            for(int i=0;i<=tot;i++)for(int j=0;j<=tot;j++)A[i][j]=0;
        }
        printf("%d
    ",f[1][0][0]);
        return 0;
    }
    View Code
  • 相关阅读:
    Search a 2D Matrix leetcode java
    Sqrt(int x) leetcode java
    Search for a Range leetcode java
    php获取客户端公网ip代码
    ddns+ros(routeros)+centos7.6+nginx+php+dnspod
    limits.conf文件修改注意事项,限制文件描述符数和进程数
    阿里云本地存储网关的一些特点和注意事项
    ROS根据访问不同的网址,走不同的路由策略的脚本
    漫威所有电影的 按时间线的观影顺序
    sklearn—特征工程
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10556215.html
Copyright © 2020-2023  润新知