zoukankan      html  css  js  c++  java
  • NFLSPC #1 String

    Link
    一个串是合法串当且仅当满足下列条件中的至少一个:
    (1.)它是空串。
    (2.)它首尾字母相同且去掉首尾字母之后是合法串。
    (3.)它可以从某个位置切开得到两个合法串。
    (f_i)表示长度为(i)的合法串个数,(g_i)表示长度为(i)的仅满足第(2)个条件的串的个数。
    显然初始状态为(f_0=1,g_0=0),转移为:

    [egin{aligned} f_i&=sum f_jg_{i-j}\ g_i&=mf_{i-2}-frac1msum g_jg_kf_{i-j-k} end{aligned} ]

    注意到有意义的下标都是偶数,因此我们令(ileftarrowfrac i2)
    考虑其OGF(F(x),G(x)),那么(F=FG+1,G=mxF+frac1mG^2F)
    那么(F(x)=frac{m+2-msqrt{1-4x-4mx}}{2(m^2x+1)}),直接(O(n))计算([x^n]F(x))即可。

    #include<cstdio>
    const int N=200007,P=998244353;
    int a[N],inv[N];
    int mod(int x){return x+(x>>31&P);}
    int pow(int a,int b){int r=1;for(;b;b>>=1,a=1ll*a*a%P)if(b&1)r=1ll*a*r%P;return r;}
    int main()
    {
        int n,m,k,ans=0,x;
        scanf("%d%d",&n,&m);
        if(n&1) return puts("0"),0;
        if(m==1) return puts("1"),0;
        n/=2,inv[0]=inv[1]=1;
        for(int i=2;i<=n||i<=2;++i) inv[i]=1ll*(P-P/i)*inv[P%i]%P;
        a[0]=1,k=1ll*pow(m-1,P-2)*m%P*inv[2]%P;
        for(int i=1;i<=n;++i) a[i]=1ll*a[i-1]*mod(4*i-6)%P*inv[i]%P;
        a[0]=mod(a[0]-pow(k,P-2)+1),x=pow(mod(1-k-k+P),P-2);
        for(int i=0,pw=1,base=1ll*k*k%P*(P-4)%P*x%P;i<=n;++i) ans=(ans+1ll*pw*a[n-i])%P,pw=1ll*pw*base%P;
        ans=1ll*ans*pow(m-1,n)%P*x%P*(P-k)%P;
        printf("%d",ans);
    }
    
  • 相关阅读:
    foj 2111 Problem 2111 Min Number
    hdoj 1175 连连看
    poj 2377 Bad Cowtractors
    poj 3666 Making the Grade
    2018华南理工大学程序设计竞赛 H-对称与反对称
    hdoj 4293 Groups
    FOJ Problem 2273 Triangles
    poj 3411 Paid Roads
    Codeforces 235A. LCM Challenge
    离散对数二连 poj 2417 Discrete Logging & HDU 2815 Mod Tree
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12926616.html
Copyright © 2011-2022 走看看