• Gym102331G Grammarly


    Link
    如果我们把所有路径以树的形式画出来,那么这会构成一棵二叉树,我们要计算的就是二叉树的节点数。
    一个节点有两个儿子当且仅当这个节点上的字符串出现了至少两种字符。
    我们称一个字符串全等当且仅当该字符串中只出现过一种字符。
    考虑一个极长全等子串(s_{l,r}),我们有({l-1+n-rchoose l-1})条路径上第一次到达的全等子串为该串,同时该字符串下是一条长度为(r-l+1)的链,贡献为({l-1+n-rchoose l-1}(r-l+1))
    同时我们还要枚举它的每一个前缀/后缀,计算有多少条路径上第一次到达的全等子串为该前缀/后缀(即强制要求最后一个删去的字符为(s_{l-1})/(s_{r+1})),这里的贡献为:
    前缀:(sumlimits_{i=l}^{r-1}{l-2+n-ichoose l-2}(i-l+1)),后缀:(sumlimits_{i=l+1}^r{i-2+n-rchoose i-1}(r-i+1))
    此时没有计算的就是非全等字符串的节点。
    这里的答案是(sumlimits_{[l,r] ext{contains at least two different characters}}{n-r+l-1choose l-1})
    考虑枚举左端点(l),设最近的合法右端点为(p_l)(显然这东西我们早就求出来了),那么答案就是(sumlimits_{l=1}^nsumlimits_{r=p_l}^n{n-r+l-1choose l-1}=sumlimits_{l=1}^nsumlimits_{i=0}^{n-p_l}{l-1+ichoose l-1}=sumlimits_{l=1}^n{l+n-p_lchoose l})

    #include<cstdio>
    #include<cstring>
    const int N=600007,P=998244353;
    int n,ans,fac[N],inv[N],ifac[N];char s[N];
    void mod(int&x){x-=P,x+=x>>31&P;}
    int C(int n,int m){return m<0||n<m? 0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
    int main()
    {
        scanf("%s",s+1),n=strlen(s+1),fac[0]=fac[1]=ifac[0]=ifac[1]=inv[0]=inv[1]=1;
        for(int i=2;i<=600000;++i) fac[i]=1ll*fac[i-1]*i%P,inv[i]=1ll*inv[P%i]*(P-P/i)%P,ifac[i]=1ll*ifac[i-1]*inv[i]%P;
        int ans=0;
        for(int l=1,r;l<=n;l=r+1)
        {
    	for(r=l;r<n&&s[r+1]==s[l];++r);
    	mod(ans+=1ll*C(l-1+n-r,l-1)*(r-l+1)%P) ;
    	for(int i=l;i<r;++i) mod(ans+=1ll*C(l-2+n-i,l-2)*(i-l+1)%P);
    	for(int i=l+1;i<=r;++i) mod(ans+=1ll*C(i-2+n-r,i-1)*(r-i+1)%P);
    	for(int i=l;i<=r;++i) mod(ans+=C(i-1+n-r,i));
        }
        printf("%d",ans);
    }
    
  • 相关阅读:
    css常见布局问题
    jsonp原理及同源策略
    执行webpack-dev-server时,提示端口被占用。
    PHP中的<<<运算符
    PHP中的字符串类型
    数据库系统的结构
    HDU 2516 取石子游戏
    常用MySql命令列选
    mysql简单语句
    微信小程序-循环
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12243013.html
Copyright © 2020-2023  润新知